一遍过,本题运用的kruskal的思想,通过并查集实现。
获得两个点以及两个点间的距离,然后从集合中找出距离的最小值。加入到图的集合中,当把所有边都遍历完后,由于这个题,图肯定是连通的。所以只要记录加进来的边的长度(也就是两点间的距离就行)。

#include<iostream>
#include<map>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;
int n;
const int maxn=101;
float res;
struct Point{
    float x,y;
};
struct G{
    int from;
    int to;
    float weight;
    inline bool operator  <(const G &g)const{
        return weight<g.weight;
    }
};
vector<G> graph;
vector<Point> vec;
int father[maxn];
int height[maxn];
void init(int n){
    for(int i=0;i<=n;i++){
        father[i]=i;
        height[i]=0;
    }graph.clear();
    vec.clear();
    res=0;
}
float getdis(Point x,Point y){
    return pow((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y),0.5);
}
int find(int x){
    if(x!=father[x]){
        father[x]=find(father[x]);
    }
    return father[x];
}
void Union(int x,int y,float weight){
    x=find(x);
    y=find(y);
    if(x!=y){
        res+=weight;
        if(height[x]>height[y]){
            father[y]=x;
        }else if(height[x]<height[y]){
            father[x]=y;
        }else{
            father[x]=y;
            height[y]++;
        }
    }
}

int main(){
    while(cin>>n){
        init(n);
        Point p;
        G g;
        for(int i=0;i<n;i++){
            cin>>p.x>>p.y;
            vec.push_back(p);
        }
        for(int i=0;i<vec.size()-1;i++){
            for(int j=i+1;j<vec.size();j++){
                g.from=i;
                g.to=j;
                g.weight=getdis(vec[i],vec[j]);
                graph.push_back(g);
            }
        }
        sort(graph.begin(),graph.end());
        for(int i=0;i<graph.size();i++){
            Union(graph[i].from,graph[i].to,graph[i].weight);
        }
        printf("%.2f\n",res);
    }
    return 0;
}