#include<cstdio> #include<vector> #include<algorithm> #include<math.h> #include<iostream> #define N 101 using namespace std; float res; struct point {//定义点集 float x; float y; }; struct G { //图,起点终点 ,距离 int from; int to; float weight; }; vector<point> vec; vector<G> graph; //并查集,在合并的时候求距离 int father[N]; int height[N]; float distance(point lhs, point rhs) {//算两点之间距离之和 return pow(pow((lhs.x - rhs.x), 2) + pow((lhs.y - rhs.y), 2), 0.5); } void Init(int n) {//初始化并查集和两个集合 for (int ic = 0 ; ic < n; ++ic) { father[ic] = ic ; height[ic] = 0; } graph.clear(); vec.clear(); res = 0; } int Find(int x) {//查 if (x != father[x]) { return Find(father[x]); } else { return father[x]; } } void Union(int x, int y, float weight) {//并 x = Find(x); y = Find(y); if (x == y) { res = res; } else { res += weight; if (height[x] > height[y]) { father[y] = x; } else if (height[y] > height[x]) { father[x] = y; } else { father[x] = y; ++ height[y] ; } } } bool comp(G lhs, G rhs) {//按权值从小到大排列 if (lhs.weight < rhs.weight) { return true; } else { return false; } } int main() { int n; point p; G g; scanf("%d", &n); Init(n); for (int iw = 0 ; iw < n ; ++iw) { cin >> p.x >> p.y; //传入点 vec.push_back(p); } for (int ix = 0 ; ix < n - 1 ; ++ix) { for (int j = ix + 1 ; j < n ; ++j) { g.from = ix; g.to = j; g.weight = distance(vec[ix], vec[j]); graph.push_back(g); } } sort(graph.begin(), graph.end(), comp); for (int idx = 0 ; idx < graph.size() ; ++idx) { Union(graph[idx].from, graph[idx].to, graph[idx].weight); } printf("%.2f\n", res); }