就是如题的做法,在一个连通图中找一条最小生成树,Kruskal的思想就是先根据所有边的权值按小到大排序,然后依次选择边进最小生成树里,但是要排除该边加进去后出现了环,生成树里是不能有环的,这样的边就不能加入,在挑选了n-1(n为图中点的个数)条边后就结束,可以证明这样构造出来的图就是最小生生成树。
再判断是否会出现环时用到并查集。
int temp = parent[r1] +parent[r2];//两根结点所带结点的总数,因为写错了这句,我检查了N久,砸墙,我很激动地写成了 int temp = Find(r1)+Find(r2);
然后各种程序各种混乱了。还有一点因为没有看见说每两个case中间要输出一个空行,然后PE了,然后改成在每个case后输两个换行符,结果还是PE,郁闷,最后只好在case输出结果之前写了一句if(不是第一个case) 输出换行。。。。。
贴代码如下:

1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <cmath> 5 #define MAXN 120 6 #define MAXM 6000 7 using namespace std; 8 int n,m; //n为城市的个数,m为边的数目m = C(n,2) 9 struct point //平面上的一个点 10 { 11 double x,y; 12 } city[MAXN]; //存各个城市的位置 13 struct ArcNode 14 { 15 int u,v; //一条边的起点和终点 16 double w; //边的长度,也就是两城市间的距离 17 bool operator <(const ArcNode & other) const 18 { 19 if(w < other.w) return true; 20 else return false; 21 }; 22 } edge[MAXM]; //存边 23 int parent[MAXN]; //用于并查集 24 double dis(point a,point b) //求两城市间距离函数 25 { 26 double d =sqrt((a.x - b.x) *(a.x - b.x) + (a.y - b.y) *(a.y - b.y) ); 27 return d; 28 } 29 int Find(int x) 30 { 31 int s; 32 for(s = x; parent[s] >= 0; s = parent[s]); 33 while(s != x) 34 { 35 int temp = parent[x]; 36 parent[x] = s; 37 x = temp; 38 } 39 return s; 40 } 41 void Union(int x,int y) 42 { 43 int r1 = Find(x); 44 int r2 = Find(y); 45 int temp = parent[r1] +parent[r2];//两根结点所带结点的总数 46 if(parent[r1] > parent[r2]) 47 { 48 parent[r1] = r2; 49 parent[r2] = temp; 50 } 51 else 52 { 53 parent[r2] = r1; 54 parent[r1] = temp; 55 } 56 } 57 double Kruskal() 58 { 59 int i; 60 for(i=0; i<n; i++) 61 parent[i] = -1; 62 int num =0; 63 double sum = 0; 64 sort(edge,edge+m); 65 for(i=0; i<m; i++) 66 { 67 int u = edge[i].u; 68 int v = edge[i].v; 69 if(Find(u) != Find(v)) 70 { 71 Union(u,v); 72 sum += edge[i].w; 73 num++; 74 } 75 if(num >= n-1) break; 76 } 77 return sum; 78 } 79 int main() 80 { 81 // freopen("in.cpp","r",stdin); 82 int ser = 0; 83 int i,j; 84 while(~scanf("%d",&n) && n!=0) 85 { 86 for(i=0; i<n; i++) 87 scanf("%lf%lf",&city[i].x,&city[i].y); 88 m = 0; 89 for(i=0; i<n; i++) 90 { 91 for(j=i+1; j<n; j++) 92 { 93 edge[m].u = i; 94 edge[m].v = j; 95 edge[m].w = dis(city[i],city[j]); 96 m++; 97 } 98 } 99 ser++; 100 if( ser != 1) printf("\n"); 101 printf("Case #%d:\n",ser); 102 printf("The minimal distance is: %.2lf\n",Kruskal()); 103 } 104 return 0; 105 }