#include #include #include #include #include using namespace std; struct Point{ int x, y; Point(int x, int y){ this->x = x; this->y = y; } }; bool compareX(Point p1, Point p2){ return p1.x != p2.x ? (p1.x < p2.x) : (p1.y < p2.y); } bool compareY(Point p1, Point p2){ return p1.y != p2.y ? (p1.y < p2.y) : (p1.x < p2.x); } double getLength(Point a, Point b){ return hypot((a.x - b.x), (a.y - b.y)); } static double mini = INT_MAX; void solveDivideAndConquer(vector vec, double sum){ double prevSum = sum; if(sum >= mini){ return; } if(vec.size() == 2){ sum += getLength(vec[0], vec[1]); mini = min(mini, sum); return; } for(int i = 0; i < vec.size() - 1; i++){ for(int j = i + 1; j < vec.size(); j++){ sum = prevSum; vector temp = vec; sum += getLength(temp[i], temp[j]); temp.erase(temp.begin() + j); temp.erase(temp.begin() + i); solveDivideAndConquer(temp, sum); } } } double solveGreedy(vector points){ vector marked(points.size(), false); double sum = 0; for(int i = 0; i < points.size(); i++){ if(!marked[i]){ marked[i] = true; int nearest = i + 1, min_dist = -1; for(int j = 0; j < points.size(); j++){ if(marked[j] || i == j) continue; int x = points[i].x - points[j].x; int y = points[i].y - points[j].y; int m_dist = x * x + y * y; if(min_dist == -1 || min_dist > m_dist){ min_dist = m_dist; nearest = j; } } marked[nearest] = true; sum += sqrt(min_dist); } } return sum; } void estimateMini(vector points){ sort(points.begin(), points.end(), compareX); double min1 = solveGreedy(points); sort(points.begin(), points.end(), compareY); double min2 = solveGreedy(points); mini = min(min1, min2); } int main(){ int n, x, y, index; vector points; string temp; getline(cin, temp); stringstream stream(temp); while(stream >> n){ index = 0; points.reserve(2 * n); for(int i = 0; i < 2 * n; i++){ stream >> x >> y; Point p(x, y); points.push_back(p); } estimateMini(points); if(n < 7) solveDivideAndConquer(points, 0); cout << fixed << setprecision(2) << mini << " "; points.clear(); } return 0; }