美文网首页
Uva(12167)(Proving Equivalences)

Uva(12167)(Proving Equivalences)

作者: kimoyami | 来源:发表于2018-08-11 16:03 被阅读0次

    链接:https://vjudge.net/problem/UVA-12167
    思路:强连通分量+缩点。最后统计出度和入度为0的点,取最大值即可
    代码:

    #include<cstdio>
    #include<deque>
    #include<vector>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    struct edge{
        int u,v;
        edge(){}
        edge(int uu,int vv):u(uu),v(vv){}
    };
    
    const int maxn = 20001;
    int t,n,m;
    vector<int> G[maxn];
    int dfn[maxn],low[maxn],sccno[maxn],in[maxn],out[maxn];
    int ntime,bcc_cnt;
    deque<int> P;
    
    void tarjan(int u){
        dfn[u] = low[u] = ++ntime;
        P.push_back(u);
        for(int i=0;i<G[u].size();i++){
            int v = G[u][i];
            if(!dfn[v]){
            tarjan(v);
            low[u] = min(low[u],low[v]);
            }
            else if(!sccno[v]){
                low[u] = min(low[u],dfn[v]);
            }
        }
        if(low[u]==dfn[u]){
            bcc_cnt++;
            int tmp;
            do{
                tmp = P.back();
                P.pop_back();
                sccno[tmp] = bcc_cnt;//一个强连通分量里面的点属于一个缩点的编号
            }while(tmp!=u);
        }
    }
    
    void find_bcc(int n){
        memset(sccno,0,sizeof(sccno));
        memset(dfn,0,sizeof(dfn));
        ntime = bcc_cnt = 0;
        for(int i=0;i<n;++i)if(!dfn[i])tarjan(i);
    }
    
    int main(){
        scanf("%d",&t);
        while(t--){
            for(int i=0;i<n;++i)G[i].clear();
            scanf("%d%d",&n,&m);
            for(int i=0;i<m;i++){
                int a,b;
                scanf("%d%d",&a,&b);
                a--;
                b--;
                G[a].push_back(b);
            }
            find_bcc(n);
            for(int i=1;i<=bcc_cnt;i++)in[i] = out[i] = 1;
                for(int u=0;u<n;u++)
                    for(int i=0;i<G[u].size();i++){
                        int v = G[u][i];
                        if(sccno[u]!=sccno[v])
                                            in[sccno[v]] = out[sccno[u]] = 0;//如果u,v不属于一个强连通分量,那么u的出度不为0,v的入度不为0!!
                    }
                    int a = 0,b=0;
                    for(int i=1;i<=bcc_cnt;i++){
                        if(in[i])a++;
                        if(out[i])b++;
                    }
                    int ans = max(a,b);
                    if(bcc_cnt==1)ans = 0;
                    printf("%d\n",ans);
        }
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:Uva(12167)(Proving Equivalences)

          本文链接:https://www.haomeiwen.com/subject/rhydbftx.html