标签:
3 3 0 1 1 1 2 1 2 0 1 4 5 0 1 1 1 2 1 2 3 1 3 0 1 0 2 2 0 0
3 5题意:有一个无向图,求它的伪森,要求每一个联通分量最多有一个环,使得伪森林的权值最大#include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> using namespace std; const int maxh=10000+10; const int maxe=100000+10; typedef struct Edge { int u,v,w; }; Edge E[maxe]; int fa[maxh],cir[maxh],n,m; void init(int num) { for(int i=0;i<=num;i++) { fa[i]=i; cir[i]=0; } } int find(int x) { if(x!=fa[x]) fa[x]=find(fa[x]); return fa[x]; } bool cmp(Edge e1,Edge e2) { return e1.w>e2.w;//降序 } bool Union(int x,int y) { int a=find(x); int b=find(y); if(a==b)//若存在环 { if(!cir[a])若之在集合不存在环 { cir[a]=1;//标记a所在集合有环 return true; } return false; } else { if(cir[a]==cir[b]&&cir[b]==1)若a,b所在集合都有环则不能合并 return false; if(cir[a]==1)若只有集合有环则可以合并或都无环则可以合并 fa[b]=a; else fa[a]=b; return true; } } int main() { int ans; while(~scanf("%d%d",&n,&m)&&(n+m)) { init(n); ans=0; for(int i=0;i<m;i++) { scanf("%d%d%d",&E[i].u,&E[i].v,&E[i].w); } sort(E,E+m,cmp); for(int i=0;i<m;i++) { if(Union(E[i].u,E[i].v)) ans+=E[i].w; } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://blog.csdn.net/letterwuyu/article/details/44968675