zoukankan      html  css  js  c++  java
  • HDU 3367 Pseudoforest (最大生成树)

    题意:给出一个图,要求出最大的pseudoforest, 所谓pseudoforest就是指这个图的一个子图,这个子图的每个连通分量中最多只能有一个环,

    而且这个子图的所有权值之和最大。这个就是所谓的伪森林。

    析:并查集,在比赛时,做了3个多小时,都没做出来,就是题意没读对,我以为就是最大生成树,但其实并不是这样的,可以不是树,是森林。。。。。

    那么我们就要去想想了,先确实两个端点是不是在同一个环里,再判断是不是各自在一个环里,再判断是不是有一个在环里,然后依次做出相应的计算即可。

    如果在一个环,或者是在各自环,那么就舍弃,如果有一个在环里,就标记,如果全不是而又形成环了,就标记,否则不标记。

    代码如下:

    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <map>
    using namespace std ;
    typedef long long LL;
    typedef pair<int, int> P;
    const int maxn = 1e4 + 5;
    const int INF = 0x3f3f3f3f;
    struct node{
        int u, v, c;
        node(int uu = 0, int vv = 0, int cc = 0) : u(uu), v(vv), c(cc) { }
        bool operator < (const node &p) const{
            return c > p.c;
        }
    };
    node a[maxn*10];
    int p[maxn];
    int vis[maxn];
    int Find(int x){  return x == p[x] ? x : p[x] = Find(p[x]); }
    
    int main(){
        int n, m;
        while(scanf("%d %d", &n, &m)){
            if(!m && !n)  break;
            memset(vis, 0, sizeof(vis));
            for(int i = 1; i <= n; ++i)  p[i] = i;
            for(int i = 0; i < m; ++i){
                int u, v, c;
                scanf("%d %d %d", &u, &v, &c);
                a[i] = node(u+1, v+1, c);
            }
    
            sort(a, a+m);
            int ans = 0;
            for(int i = 0; i < m; ++i){
                int x = Find(a[i].u);
                int y = Find(a[i].v);
                if(x == y){
                    if(!vis[x] && !vis[y]){
                        ans += a[i].c;
                        vis[x] = vis[y] = 1;
                        p[y] = x;
                    }
                }
                else{
                    if(!vis[x] && !vis[y]){
                        ans += a[i].c;
                        p[y] = x;
                    }
                    else if(!vis[x] || !vis[y]){
                        ans += a[i].c;
                        vis[x] = vis[y] = 1;
                        p[y] = x;
                    }
                }
            }
    
            cout << ans << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    PWA渐进式增强WEB应用
    如何去掉wordpress头部<link rel='next' href='*/page/2' />
    wordpress修改邮箱提示There is a pending change of your email to
    使用WP-China-Yes让你的wordpress告别429错误
    Focus
    α_β_γ_δ_ε_ζ_η_θ_ι_κ_λ_μ_ν怎么读
    Ubuntu总结常用命令记录
    声明
    你所不知道的冰冷的经济真相(转自来自天涯大佬)
    杨振宁演讲谈这件事:我很高兴中国政府没有上当
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5709349.html
Copyright © 2011-2022 走看看