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;
    }
    
  • 相关阅读:
    谈我们为什么学不好编程2——你是否已进入“等死模式”?
    JSP使用SmartUpload实现文件上传
    内核模块编程练习
    Vue++:Vue中 关于$emit的用法
    Vue++:Vue 脚手架在vue.config.js文件中配置scss全局变量
    Vue++:Vuecli3.0 脚手架搭建项目
    Java++:七个开源的 Spring Boot 前后端分离项目,一定要收藏!
    MySQL++:SQL 优化的15个小技巧
    RabbitMQ++:RabbitMQ 的队列(Queue)的参数及其含义
    Vue++:Vue 二级路由不显示页面问题
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5709349.html
Copyright © 2011-2022 走看看