zoukankan      html  css  js  c++  java
  • hdu 5438(拓扑+bfs)

    题意:建图,删掉所有连接点小于2的点,直到不能删为止,问最后剩余的联通块中,点的数量是奇数的联通块中的点的权值和。


    思路:拓扑删点,bfs计算


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <queue>
    using namespace std;
    typedef long long ll;
    vector<int>q[10005];
    int p[10005];
    int vis[10005];
    int in[10005];
    int Q[10005];
    ll ans,num;
    queue<int>que;
    
    void bfs()
    {
        while(!que.empty())
        {
            int u = que.front();
            que.pop();
            if(vis[u])
                continue;
            vis[u] = 1;
    
            num++;
            ans+= p[u];
            for(int i = 0; i < q[u].size(); i++)
            {
                int x = q[u][i];
                if(in[x] < 2)
                    continue;
                que.push(x);
            }
        }
        return;
    }
    int n;
    void topsort()
    {
        int head_=1,tail=0;
        for(int i=1; i<=n; i++)
            if(in[i] < 2 && in[i] > 0)
            {
                Q[++tail]=i;
                in[i] -= 2;
            }
        while (head_<=tail)
        {
            int now=Q[head_];
            for(int j=0; j < q[now].size(); j++)
            {
                int v = q[now][j];
                in[v]--;
                if (in[v] < 2 && in[v]>0)
                {
                    in[v]-=2;
                    Q[++tail]=v;
                }
            }
            head_++;
        }
    }
    
    int main()
    {
        int T,m,a,b;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i = 1; i <= n; i++)
                scanf("%d",&p[i]);
            memset(in,0,sizeof(in));
            memset(vis,0,sizeof(vis));
            for(int i = 1; i <= m; i++)
            {
                scanf("%d%d",&a,&b);
                q[a].push_back(b);
                q[b].push_back(a);
                in[a]++;
                in[b]++;
            }
            topsort();
            while(!que.empty())
                que.pop();
            ll all=0;
            for(int i = 1; i <= n; i++)
            {
                if(!vis[i] && in[i] >= 2)
                {
                    ans = 0;
                    num = 0;
                    que.push(i);
                    bfs();
                    if(num %2 == 1)
                    {
                        all += ans;
                    }
                }
            }
            if(n==1)
                printf("0
    ");
            else
                printf("%I64d
    ",all);
            for(int i = 1; i <= n; i++)
            {
                q[i].clear();
            }
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    堆排序
    我花了一年时间来学机器学习
    一个由进程内存布局异常引起的问题
    老曹眼中的Linux基础
    Select模型原理
    socket编程的select模型
    [插件] 如何在一个页面中使用多个SWFUpload对象上传文件
    [算法] 拖动排序
    [算法] 应用版本更新逻辑
    [oracle] 如何使用myBatis在数据库中插入数据并返回主键
  • 原文地址:https://www.cnblogs.com/Przz/p/5409759.html
Copyright © 2011-2022 走看看