求一个最大的生成森林,每个连通的部分最多有一个环,求其权值最大的森林。。。。
比如说各个点都有各自的一个集合,那么对于新读入的2点,若他们这个集合里面已经有环,就不能在忘这里面添加边了,再添加边必定会构成新的环,若他们属于两个不同的集合,若他们两个集合都有环了,不能在把他们连起来了,若有一个环那么连起来以后还要标记打的集合里面有环
#include"stdio.h" #include"stdlib.h" #include"string.h" int set[10001],v[10001]; struct node { int x,y,dis; }aa[100001]; int find(int x) { int r,i; r=x; while(set[r]!=r) r=set[r]; while(set[x]!=r) { i=set[x]; set[x]=r; x=i; } return r; } int cmp(const void*a,const void*b) { return (*(struct node*)b).dis-(*(struct node*)a).dis; } int merge(int x,int y) { int fx,fy; fx=find(x); fy=find(y); if(fx==fy) { if(!v[fx]) { v[fx]=1;return 1; } return 0; } if(v[fx]&&v[fy]) return 0; if(v[fx])//? set[fy]=fx; else set[fx]=fy; return 1; } int main() { int i,j,k,ans,n,m; while(scanf("%d%d",&n,&m)!=-1) { if(n==0&&m==0)break; for(i=0;i<n;i++) { set[i]=i; v[i]=0; } for(i=0;i<m;i++) scanf("%d%d%d",&aa[i].x,&aa[i].y,&aa[i].dis); qsort(aa,m,sizeof(aa[0]),cmp); ans=0; for(i=0;i<m;i++) { if(merge(aa[i].x,aa[i].y)) ans+=aa[i].dis; } printf("%d\n",ans); } return 0; }