题解:kruskal算法模板
krcukal算法:
对边进行排序,从最小的开始加入集合,每次都检查是不是构成了环,如果有环,说明这条边是多余的,因为这条边所能实现的联通的功能,已经被前面更短的边实现了。
#include<iostream> #include<algorithm> using namespace std; const int maxn=10005; struct node { int from,to,len;} edge[maxn]; int n,fa[maxn],m,ans,q; bool cmp(node a,node b) { return a.len<b.len; } int Find(int x) { if(fa[x]==x) return x; return fa[x]=Find(fa[x]); } void Merge(int x,int y) { x=Find(x),y=Find(y); if(x!=y) fa[y]=x; } int kruskal() { sort(edge,edge+m,cmp); for(int i=0;i<=n;i++) fa[i]=i;//初始化并查集 ans=0; for(int i=0;i<m;i++)//一条边的两个端点不在同一个集合,则选它,并合并端点 if(Find(edge[i].from)!=Find(edge[i].to)) Merge(edge[i].from,edge[i].to),ans+=edge[i].len; return ans; } int main() { while(cin>>n,n) { m=n*(n-1)/2; for(int i=0;i<m;i++) cin>>edge[i].from>>edge[i].to>>edge[i].len; cout<<kruskal()<<endl; } return 0; }