hdu 3367 Pseudoforest
Posted SDAU_ZG
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 3367 Pseudoforest相关的知识,希望对你有一定的参考价值。
The last test case is followed by a line containing two zeros, which means the end of the input.
1.两个端点属于同一个集合。如果这个集合还没有环,那么就加上这条边并标记次集合有环
2.两个端点属于不同的集合。如果这两个集合至多只有一个集合有环的话,那么就可以加上这条边合并这两个集合,一定记得要修改合并后集合的环标志。
代码:
#include <iostream>
#include<stdio.h>
#include<algorithm>
#define maxn 100010
using namespace std;
int n,m;
typedef struct edge
{
int u,v,w;
} Edge;
Edge e[maxn];
int fa[maxn];
int loop[maxn];
int cmp(const void *a,const void *b)
{
Edge* aa = (Edge*)a;
Edge* bb = (Edge*)b;
return bb->w - aa->w;
}
int MyFind(int a)
{
return fa[a] == a?a:fa[a] = MyFind(fa[a]);
}
int main()
{
while(true)
{
scanf("%d %d",&n,&m);
if(n+m == 0) break;
for(int i = 0; i < n; i++)
{
fa[i] = i;
loop[i] = 0;
}
for(int i = 0; i < m; i++)
{
scanf("%d %d %d",&e[i].u,&e[i].v,&e[i].w);
}
qsort(e,m,sizeof (Edge),cmp);
int ans = 0;
for(int i = 0 ; i < m; i++)
{
int u = e[i].u;
int v = e[i].v;
int w = e[i].w;
int fa_u = MyFind(u);
int fa_v = MyFind(v);
if(fa_u == fa_v )
{
if(!loop[fa_u])
{
loop[fa_u] = 1;
ans+=w;
}
}
else
{
if(loop[fa_u] + loop[fa_v] < 2) //两个连通分量至多一个环
{
fa[fa_v] = fa_u;
loop[fa_u] += loop[fa_v]; //改变环标记,父节点的环标记为两个集合的环数目的和
ans+=w;
}
}
}
printf("%d\n",ans);
}
return 0;
}
以上是关于hdu 3367 Pseudoforest的主要内容,如果未能解决你的问题,请参考以下文章