求一个最大的生成森林,每个连通的部分最多有一个环,求其权值最大的森林。。。。
比如说各个点都有各自的一个集合,那么对于新读入的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;
}