畅通工程的升级版。
求最小生成树。Kruskal 算法:应用并查集。
#include<iostream> #include<algorithm> using namespace std; int p[102]; bool Init(int n) //一开始指向自己 { for(int i=0;i<=n;i++) p[i]=i; return true; } int Find(int x) //找到根节点 { int r,i,j; r=x; while(r!=p[r]) r=p[r]; //路径压缩准备,找到根节点 i=x; while(i!=p[i]) { j=p[i]; p[i]=r; i=j; } return i; //返回根节点 } bool Merge(int x,int y) //返回是否需要合并 { int tx,ty; tx=Find(x); ty=Find(y); if(tx==ty) return false; p[tx]=ty; return true; } struct Path { int a,b; int v; }; bool cmp(Path a,Path b) { return a.v<b.v; } int main() { int n,i,sum,cnt; Path pa[5002]; while(scanf("%d",&n)==1&& n) { for(i=0;i<n*(n-1)/2;i++) scanf("%d%d%d",&pa[i].a,&pa[i].b,&pa[i].v); sort(pa,pa+n*(n-1)/2,cmp); //根据路劲从小到大排序 sum=0; cnt=1; Init(n); for(i=0;cnt<n;i++) //找到n-1一条路 if(Merge(pa[i].a,pa[i].b)) { sum+=pa[i].v; cnt++; } printf("%d\n",sum); } return 0; }
时间: 2024-10-29 04:02:02