zoukankan      html  css  js  c++  java
  • Ponds----hdu5438(拓扑排序)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5438

     

    题意:有n个池塘和m个管道;每个池塘的价值是v, 现在由于资金问题要删除池塘;但是删除的池塘必须是最多只连接一个管道,否则会爆炸;

    求最后相连的池塘有奇数个的价值总和是多少;

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<vector>
    #include<queue>
    using namespace std;
    #define N 100100
    #define INF 0xfffffff
    
    int v[N], f[N], du[N], vis[N], a[N], b[N], sum[N];
    vector<vector<int> > G;
    
    int Find(int x)
    {
        if(x!=f[x])
            f[x] = Find(f[x]);
        return f[x];
    }
    
    int main()
    {
        int T, n, m;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d%d", &n, &m);
    
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &v[i]);
                f[i] = i;
                sum[i] = du[i] = vis[i] = 0;
            }
            G.resize(n+1);
            G.clear();
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d", &a[i], &b[i]);
    
                du[a[i]]++;
                du[b[i]]++;
                G[a[i]].push_back(b[i]);
                G[b[i]].push_back(a[i]);
            }
            queue<int>Q;
            for(int i=1; i<=n; i++)
            {
                if(du[i]<2)///把度为<2的入队,并删除;
                {
                    vis[i] = 1;
                    Q.push(i);
                }
            }
            while(!Q.empty())
            {
                int p=Q.front();
                Q.pop();
                int len = G[p].size();
                for(int j=0; j<len; j++)
                {
                    int q = G[p][j];
                    du[q]--;
                    if(vis[q]==0 && du[q]<2)
                    {
                        Q.push(q);
                        vis[q] = 1;
                    }
                }
            }
            
            for(int i=1; i<=m; i++)///让有联系的放到一个集合里
            {
                if(!vis[a[i]] && !vis[b[i]])
                {
                    int pa = Find(a[i]);
                    int pb = Find(b[i]);
                    if(pa != pb)
                        f[pb] = pa;
                }
            }
            for(int i=1; i<=n; i++)
            {
                if(!vis[i])
                    sum[Find(i)]++;///记录每个连通图的个数;
            }
            long long ans = 0;
            for(int i=1; i<=n; i++)
            {
                if(!vis[i] && sum[f[i]]%2==1)///判断是否有奇数个;
                    ans+=v[i];
            }
            printf("%I64d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Canvas与Paint的0基础使用
    PHP经常使用功能
    java枚举在android项目应用
    POJ1833 &amp; POJ3187 &amp; POJ3785 next_permutation应用
    usb芯片调试经验
    Equals和==比較
    JSTL标准标签库具体解释
    零基础学python-3.3 标识符
    用react native 做的一个推酷client
    Linux异常关机后,Mysql启动出错ERROR 2002 (HY000)
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4811370.html
Copyright © 2011-2022 走看看