模板-并查集

来源:互联网 发布:网络大电影人群分析 编辑:程序博客网 时间:2024/05/16 17:42
//kruskal算法,并查集 #include<iostream>#include<cstdio>#include<algorithm>const int maxn=300005;using namespace std;int n,m;int tot;int ans;int fa[maxn];struct edge{int u;int v;int w;}e[300005];int find(int x)//寻找每棵树的根节点 {if(fa[x]==x) return x;return fa[x]=find(fa[x]);}void uni(int x,int y)//uni init find  并查集。//uni:将这棵树的根节点接到另一棵树上,两树合并 {x=find(x);y=find(y);fa[x]=y;return;}void init(int n)//将所有点重置为根节点 {for(int i=0;i<=n;i++)fa[i]=i;}bool cmp(edge x,edge y){if(x.w<y.w)return 1;elsereturn 0;}void kruskal(){for(int i=1;i<=m;i++){if(find(e[i].u)==find(e[i].v))//如果两点根节点相同即在一棵树上,继续 continue;else{uni(e[i].u,e[i].v);//两树并为一棵树 ans+=e[i].w;//边的权值累加 }//printf("%d %d %d\n",e[i].u,e[i].v,e[i].w);}return;}int main(){while(scanf("%d%d",&n,&m)!=EOF){if(!n && !m)break;init(n);//重置 ans=0;tot=0;//非常重要,有多组数据,重置 for(int i=1;i<=m;i++){scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);tot+=e[i].w;//总权值 }sort(e+1,e+m+1,cmp);//排序,贪心 kruskal();//查找 printf("%d\n",tot-ans);//printf("test %d %d\n",tot,ans);}return 0;}

原创粉丝点击