HDU problem h

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




猜你喜欢

转载自blog.csdn.net/sdau_fangshifeng/article/details/80374856
今日推荐