• 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
  • 相关阅读:
    MySQL教程22-字符串类型
    MySQL教程21-日期和时间类型
    MySQL教程20-小数类型
    MySQL教程19-整数类型
    MySQL教程18-数据类型简介
    ActiveMQ_topic
    ActiveMQ_消费者编码
    ActiveMQ_生产者编码
    ActiveMQ介绍
    管理docker容器
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4811370.html
Copyright © 2020-2023  润新知