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;
    }
    
  • 相关阅读:
    css 实现div内显示两行或三行,超出部分用省略号显示
    vue组件中的样式属性:scoped,解决在父组件中无法修改子组件样式问题
    HBuilder打包app(vue项目)
    vue动态路由传值以及get传值及编程式导航
    vue路由vue-router的安装和使用
    vue组件传值之父传子
    vue生命周期钩子函数
    vue定义组件
    vue定义自定义事件方法、事件传值及事件对象
    vue中操作Dom节点的方法
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5709349.html
Copyright © 2011-2022 走看看