杭电题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1233
还是畅通工程
Time Limit : 4000/2000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 26 Accepted Submission(s) : 18
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( < 100 );随后的N(N-1)/2行对应村庄间的距离,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间的距离。为简单起见,村庄从1到N编号。 当N为0时,输入结束,该用例不被处理。
Output
对每个测试用例,在1行里输出最小的公路总长度。
Sample Input
3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0
Sample Output
3
5
Hint
Hint Huge input, scanf is recommended.
Source
浙大计算机研究生复试上机考试-2006年
1 // 最小生成树(kruskal算法)+并查集 2 #include <stdio.h> 3 #define Max 9999999 4 int f[101]; 5 int n; 6 7 struct Node 8 { 9 int x,y; 10 int cost; 11 }node[10001]; 12 13 int Find(int x) //查找函数,若是都在集合中,最终得到的都是集合中最后一个元素 14 { 15 if(f[x]!=x) 16 f[x]=Find(f[x]); 17 18 return f[x]; 19 } 20 21 int main() 22 { 23 int i,j,min,x,y,sum; 24 while(scanf("%d",&n)==1&&n) 25 { 26 min=sum=0; 27 for(i=1;i<=n;i++) 28 f[i]=i; 29 for(i=1;i<=n*(n-1)/2;i++) 30 { 31 scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].cost); 32 j=i; 33 while(j>0&&node[j].cost<node[j-1].cost) //插入排序 34 { 35 struct Node tmp=node[j]; 36 node[j]=node[j-1]; 37 node[j-1]=tmp; 38 j--; 39 } 40 } 41 for(i=1;i<=n*(n-1)/2;i++) 42 { 43 x=Find(node[i].x); 44 y=Find(node[i].y); 45 if(x!=y) //判断元素是否在一个集合内,若不在则插入元素到末尾 46 { 47 f[x]=node[i].y; 48 min+=node[i].cost; 49 sum++; 50 } 51 if(sum==n) break; 52 } 53 printf("%d\n",min); 54 55 /* for(i=1;i<=n*(n-1)/2;i++) 56 printf("%d%d%d\n",node[i].x,node[i].y,node[i].cost);*/ 57 } 58 return 0; 59 }