1 题目编号:1008
2 题目内容:
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
3 解题思路形成过程:每输入一条边,判断此边两端点是不是在同一颗树上,如果在同一颗树上,判断树是不是有环,如果有环,则不加入此边,如果没环,加入此边(合并);如果两棵树都没有环,直接合并即可,如果只有一棵树有环,可以合并,并标记,如果都有环,显然不能合并
4 代码:
#include<iostream>
using namespace std;
#define M 100005
#define N 10005
struct node
{
int x,y;
int len;
}g[M];
int cmp(const void *a,const void *b)
{
return (*(node *)b).len - (*(node *)a).len;
}
int father[M],n;
int cha(int x)
{
if(x==father[x])
return x;
father[x]=cha(father[x]);
return father[x];
}
int bing(int x,int y)
{
father[cha(x)]=cha(y);
return 0;
}
int main()
{
int k,x,y,z,m,i,ans;
int used[N];
while(scanf("%d%d",&n,&m)&&(m||n))
{
for(i=0;i<m;i++)
{
scanf("%d%d%d",&g[i].x,&g[i].y,&g[i].len);
}
for(i=0;i<=n;i++)
father[i]=i;
k=0;
// int max=0;
ans=0;
qsort(g,m,sizeof(g[0]),cmp);
memset(used,0,sizeof(used));
for(i=0;i<m;i++)
{
x=g[i].x;
y=g[i].y;
z=g[i].len;
int ca=cha(x);
int cb=cha(y);
if(ca!=cb)
{
if(used[ca]==0 || used[cb] ==0)
{
ans+=z;
if(used[cb] == 1)
bing(x,y);
else
bing(y,x);
}
}
else if(used[ca]==0)
{
used[ca] = 1;
ans+=z;
}
}
cout<<ans<<endl;
}
return 0;
}