L - 还是畅通工程
某省调查乡村交通状况,得到的统计表中列出了任意两村庄间的距离。省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可),并要求铺设的公路总长度为最小。请计算最小的公路总长度。
当N为0时,输入结束,该用例不被处理。
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
3 5#include<cstdio> #include<algorithm> int f[100+11]; int ran[100+11]; //表示树的高度 using namespace std; struct node { int u,v; long long dis; }data[5000+11]; bool cmp(node A,node B) { return A.dis <B.dis ; } int find(int x) { if(x==f[x]) return x; else return f[x]=find(f[x]); } void join(int x,int y) { int nx,ny; nx=find(x); ny=find(y); if(nx==ny) return ; else { if(ran[nx]<ran[ny]) f[nx]=ny; //将较低的树连到较高的树上面 else { f[ny]=nx; if(ran[nx]==ran[ny]) ran[nx]++; //两棵树的高度相同,相连之后,任意一棵加一 } } } int main() { int N,T; while(scanf("%d",&N),N) { long long sum=0; T=N*(N-1)/2; for(int i=1;i<=N;i++) { f[i]=i; ran[i]=0; } for(int j=0;j<T;j++) { scanf("%d%d%lld",&data[j].u,&data[j].v ,&data[j].dis ); } sort(data,data+T,cmp); for(int j=0;j<T;j++) { if(find(data[j].u )!=find(data[j].v )) //树,不能成环 { sum+=data[j].dis; join(data[j].u,data[j].v ); } } printf("%lld\n",sum); } return 0; }
Huge input, scanf is recommended.
Hint