zoukankan      html  css  js  c++  java
  • HDU2767Proving Equivalences(有向图强连通分量)

    有向图强连通分量

    题意:要求添加尽量少的边使得新图强连通。

    先求强连通分量,再进行缩点形成新图,然后求新图入度为0的个数和出度为0的个数的最大值即是答案;

    View Code
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <stack>
    #define MAXN 20000+50
    using namespace std;
    
    int n,m;
    vector<int>G[MAXN];
    int lowlink[MAXN],sccno[MAXN],pre[MAXN];
    int scc_cnt,dfs_clock;
    stack<int> S;
    void dfs(int u)
    {
        pre[u]=lowlink[u]=++dfs_clock;
        S.push(u);
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            if(!pre[v])
            {
                dfs(v);
                lowlink[u]=min(lowlink[u],lowlink[v]);
            }else if(!sccno[v])
            {
                lowlink[u]=min(lowlink[u],pre[v]);
            }
        }
        if(lowlink[u]==pre[u])
        {
            scc_cnt++;
            for(;;){
            int t=S.top();S.pop();
            sccno[t]=scc_cnt;
            if(t==u)break;
            }
        }
    }
    void find_scc(){
        memset(sccno,0,sizeof(sccno));
        memset(lowlink,0,sizeof(lowlink));
        memset(pre,0,sizeof(pre));
        dfs_clock=0,scc_cnt=0;
        for(int i=1;i<=n;i++)
            if(!pre[i])dfs(i);
    }
    int in[MAXN],out[MAXN];
    int main()
    {
        int cas;
        scanf("%d",&cas);
        while(cas--)
        {
            scanf("%d%d",&n,&m);
            for(int i=0;i<=n;i++)
                G[i].clear();
            int a,b;
            for(int i=0;i<m;i++)
            {
                scanf("%d%d",&a,&b);
                G[a].push_back(b);
            }
            find_scc();
            memset(in,0,sizeof(in));
            memset(out,0,sizeof(out));
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<G[i].size();j++)
                {
                    int v=G[i][j];
                    if(sccno[i]!=sccno[v])
                    {
                        in[sccno[v]]=out[sccno[i]]=1;
                    }
                }
            }
            a=0,b=0;
            for(int i=1;i<=scc_cnt;i++)
            {
                if(in[i]==0)a++;
                if(!out[i])b++;
            }
            if(scc_cnt==1)a=0,b=0;
            printf("%d\n",max(a,b));
        }
        return 0;
    }
  • 相关阅读:
    LC.225. Implement Stack using Queues(using two queues)
    LC.232. Implement Queue using Stacks(use two stacks)
    sort numbers with two stacks(many duplicates)
    LC.154. Find Minimum in Rotated Sorted Array II
    LC.81. Search in Rotated Sorted Array II
    LC.35.Search Insert Position
    前后端分离:(一)
    Redis基本使用(一)
    GIT篇章(二)
    GIT篇章(一)
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2863198.html
Copyright © 2011-2022 走看看