Problem Description
In graph theory, a pseudoforest is an undirected graph in which every connected component has at most one cycle. The maximal pseudoforests of G are the pseudoforest subgraphs of G that are not contained within any larger pseudoforest of G. A pesudoforest is larger than another if and only if the total value of the edges is greater than another one’s.<br><br>
Input
The input consists of multiple test cases. The first line of each test case contains two integers, n(0 < n <= 10000), m(0 <= m <= 100000), which are the number of the vertexes and the number of the edges. The next m lines, each line consists of three integers, u, v, c, which means there is an edge with value c (0 < c <= 10000) between u and v. You can assume that there are no loop and no multiple edges.<br>The last test case is followed by a line containing two zeros, which means the end of the input.<br>
Output
Output the sum of the value of the edges of the maximum pesudoforest.<br>
Sample Input
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
Sample Output
3 5
题意:
看了好久,加查资料才看懂题意
意思是,一个图,每个节点之间存在连接权值,允许存在一个环,问最大的权值和是多少
存在一个环的森林最大权值
code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
int fa[10010];
struct node
{
int x;
int y;
int v;
}s[100010];
bool u[10010];
int Find(int x)
{
if(fa[x]!=x)
fa[x]=Find(fa[x]);
return fa[x];
}
bool cmp(node n1,node n2)
{
return n1.v>n2.v;
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)&&(n+m))
{
for(int i=0;i<n;++i)
fa[i]=i,u[i]=true;
for(int i=0;i<m;++i)
scanf("%d%d%d",&s[i].x,&s[i].y,&s[i].v);
long long ans=0;
sort(s,s+m,cmp);
for(int i=0;i<m;++i)
{
int a=Find(s[i].x);
int b=Find(s[i].y);
if(a==b)//祖先相同
{
//判断是否存在环
if(u[a]&&u[b])//都不存在环,连接,形成环
{
ans+=s[i].v;//累加
u[a]=u[b]=0;
}
}
else
{
if(u[a]&&u[b])//没有环
{
ans+=s[i].v;
fa[a]=b;//连接
}
else if(u[a]||u[b])//存在一个环
{
ans+=s[i].v;
u[a]=u[b]=0;//记录已有一个环
fa[a]=b;//连接
}
}
}
printf("%lld\n",ans);
}
return 0;
}
//完美的代码