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; }//完美的代码