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;
    }
    
  • 相关阅读:
    HDU2059(龟兔赛跑)
    pat 1012 The Best Rank
    pat 1010 Radix
    pat 1007 Maximum Subsequence Sum
    pat 1005 Sign In and Sign Out
    pat 1005 Spell It Right
    pat 1004 Counting Leaves
    1003 Emergency
    第7章 输入/输出系统
    第六章 总线
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5709349.html
Copyright © 2011-2022 走看看