Pseudoforest(伪最大生成树)

Pseudoforest

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 389 Accepted Submission(s): 165
 

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.


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.
The last test case is followed by a line containing two zeros, which means the end of the input.


Output

Output the sum of the value of the edges of the maximum pesudoforest.


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

 

Source

“光庭杯”第五届华中北区程序设计邀请赛 暨 WHU第八届程序设计竞赛


Recommend

lcy

/*
初级想方法,最大生成树再加一条最长边
讲解:没看明白题意的傻逼想法,题目说不是最大生成树,森林也可以,但是最多只能有一个环

正解:将所有的边都加到树上,加的时候如果两点在同一个并查集:如果原来有环就不能加
如果不在同一个并查集:如果原来两个都有环不能加
*/
#include<bits/stdc++.h>
using namespace std;
struct node
{
    int u,v,val;
    node()
    {}
    node(int a,int b,int c)
    {
        u=a;
        v=b;
        val=c;
    }
    bool operator < (const node &a) const
    {
        return val>a.val;
    }
};
vector<node>edge;
int bin[10005];
int n,m;
int x,y,val;
int h[10005];//表示当前集合有没有环
long long cur=0;
void init()
{
    for(int i=0;i<=n;i++)
    {
        bin[i]=i;
        h[i]=0;
    }
    edge.clear();
    cur=0;
}
int findx(int x)
{
    int temp=x;
    while(x!=bin[x])
        x=bin[x];
    bin[temp]=x;
    return x;
}
int main()
{
    //freopen("C:\\Users\\acer\\Desktop\\in.txt","r",stdin);
    while(scanf("%d%d",&n,&m)!=EOF&&(n||m))
    {
        init();
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&x,&y,&val);
            edge.push_back(node(x,y,val));
        }
        sort(edge.begin(),edge.end());
        for(int i=0;i<edge.size();i++)
        {
            int fx=findx(edge[i].u);
            int fy=findx(edge[i].v);
            if(fx==fy)//两个原来就是一个并查集的就可能产生环了
            {
                if(h[fx])//有环了
                    continue;
                cur+=edge[i].val;
                h[fx]=1;
            }
            else
            {
                if(h[fx]&&h[fy])//两个集合都有环不可以
                    continue;
                bin[fy]=fx;
                cur+=edge[i].val;
                if(h[fx]||h[fy])
                    h[fx]=1;
            }
        }
        printf("%lld\n",cur);
    }
    return 0;
}
时间: 2024-10-12 09:55:38

Pseudoforest(伪最大生成树)的相关文章

HDU 3367 Pseudoforest(伪森林)(并查集)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3367 题意:在图论中,如果一个森林中有很多连通分量,并且每个连通分量中至多有一个环,那么这个森林就称为伪森林. 现在给出一个森林,求森林包含的最大的伪森林,其大小通过所有边的权值之和来比较. 分析: 1.一开始想的是:在每个连通分量中求一个最大生成树,然后加一条最大的边,再把每个连通分量算出来的值加起来,但WA了.这并不是最优的,因为还存在这种情况:一个连通分量里最初有两个环,但是伪森林要求最多一个

HDU 3367 Pseudoforest 最大生成树

题目来源:HDU 3367 Pseudoforest 题意:每个连通块最多可以有一个环 求最大的森林 思路:考虑最大生成树 如果祖先一样没有环 那就合并 如果祖先不一样 如果2棵树都没有环 合并 如果有1棵树有环 合并 标记该棵树有环 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100010; struct edge { i

【hdu3367】Pseudoforest(伪森林)

http://acm.hdu.edu.cn/showproblem.php?pid=3367 题目大意 伪森林就是一个无向图,这个无向图有多个连通块且每个连通块只有一个简单环. 给你一个无向图,让你找这个图的一个最大生成伪森林(即边权之和最大). 题解 考虑到用Kruscal算法搞最大生成树时,每次加入一条边之前都必须保证边的这两点在之前属于两个连通块,就是为了防止出现环. 即如果加入的边的两点在一个没有环的连通块里的话,就会出现一个环. 那么我们把Kruscal算法改造一下,如果这条边的两点在

hdu 3367 Pseudoforest【伪森林】

Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1929    Accepted Submission(s): 745 Problem Description In graph theory, a pseudoforest is an undirected graph in which every conne

(hdu step 6.1.8)Pseudoforest(求有一个环的最大生成树)

题目: Pseudoforest Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 283 Accepted Submission(s): 122   Problem Description In graph theory, a pseudoforest is an undirected graph in which every connec

hdu 3367 Pseudoforest 最大生成树★

1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 using namespace std; 6 7 const int maxn = 100005; 8 int n, m; 9 struct node 10 { 11 int u, v, c; 12 }g[maxn]; 13 long long ans; 14 int fa[maxn];

(最大生成树) hdu 3367

Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1957    Accepted Submission(s): 756 Problem Description In graph theory, a pseudoforest is an undirected graph in which every connec

HDU 3367 Pseudoforest

https://vjudge.net/problem/HDU-3367 题意: 一个伪森林是一个每个连通分量至多有一个环的无向图,给出一个图,图中不包含重边和圈,请你求出这个图的权值最大的伪森林. 思路: 一开始想的是用最大生成树,然后加一条最大的不在生成树中的边,wa了,真是可笑题意都没有理解清楚.题中的图可以是非连通的. 之后看了题解,发现是用并查集的思路,先把边从大到小进行排序,之后对于每一条边,我们看它的两个点a,b. 有2大的种情况: 1.a,b在一个连通分量中,并且他们没有被标记,则

HDOJ 题目3367 Pseudoforest(并查集)

Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1932    Accepted Submission(s): 746 Problem Description In graph theory, a pseudoforest is an undirected graph in which every conne