~欢迎你!第 AmazingCounters.com 位造访者

ACM: 还是畅通工程-并查集-最小生成树-解题报

还是畅通工程
Time Limit:2000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

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.
        
练习题。。。
AC代码:
#include"iostream"
#include"cstdio"
#include"algorithm"
#include"cmath"
#include"cstring"
using namespace std;

int pe[200];
struct node {
	int a,b,m;
} vill[10000];

int find(int x) {
	return pe[x]==x?x:(pe[x]=find(pe[x]));
}

bool cmpm(node a,node b) {
	return a.m<b.m;
}

int main() {
	int n,m,num;
	long long tot;
	while(~scanf("%d",&n)) {
		if(!n)break;
		tot=0;
		num=n-1;
		for(int i=0; i<=n; i++) {
			pe[i]=i;
		}
		int nn=n*(n-1)/2;
		for(int i=0; i<nn; i++) {
			scanf("%d%d%d",&vill[i].a,&vill[i].b,&vill[i].m);
		}
		sort(vill,vill+nn,cmpm);
		for(int i=0; i<nn; i++) {
			int rt1=find(vill[i].a);
			int rt2=find(vill[i].b);
			if(rt1!=rt2) {      //如果没修路就修m最小的一条路,记录总长度 
				pe[rt2]=rt1;
				tot+=vill[i].m;
				num--;			//孤立的村庄的个数。
				if(num==0)break;
			}
		}
		printf("%I64d\n",tot);
	}
	return 0;
}

  

posted @ 2016-07-24 14:31  ~HDMaxfun  阅读(174)  评论(0编辑  收藏  举报