zoukankan      html  css  js  c++  java
  • poj2186Popular Cows+tarjan缩点+建图

    传送门:

    题意:

    给出m条关系,表示n个牛中的崇拜关系,这些关系满足传递性。问被所有牛崇拜的牛有几头;

    思路:

    先利用tarjan缩点,同一个点中的牛肯定就是等价的了,建立新的图,找出其中出度为0的点。如果这个点唯一,那么答案就是这个缩点中包含的所有点。

    如果不唯一,那么答案不存在。因为有两个点出度为0,说明这两个点相互不羡慕,0。如果没有出度为0的点,说明缩点有问题;

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <map>
    #include <set>
    #include <queue>
    #include <stack>
    #include <list>
    #include <iterator>
    
    using namespace std;
    
    const int maxn = 10009;
    int n,m,dfn[maxn],low[maxn],vis[maxn],belong[maxn],tot,scc;
    int num[maxn];
    stack<int>s;
    vector<int>mp[maxn];
    vector<int>nn[maxn];
    void init(){
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(vis,0,sizeof(vis));
        memset(belong,0,sizeof(belong));
        memset(num,0,sizeof(num));
        tot = 0;
        scc = 0;
        for(int i=1; i<=n; i++)
            mp[i].clear(),nn[i].clear();
        while(!s.empty())s.pop();
    }
    void tarjan(int x)
    {
        dfn[x] = low[x] = ++tot;
        s.push(x);vis[x] = 1;
        for(int i=0; i<mp[x].size(); i++)
        {
            int v = mp[x][i];
            if(!dfn[v])
            {
                tarjan(v);
                low[x] = min(low[v],low[x]);
            }
            else if(vis[v])
            {
                low[x] = min(low[x],dfn[v]);
            }
        }
        if(low[x] == dfn[x])
        {
            scc++;
            while(1)
            {
                int o = s.top();
                s.pop();
                vis[o] = 0;
                belong[o] = scc;
                num[scc]++;
                if(o==x)break;
            }
        }
    }
    void solve()
    {
        for(int i=1; i<=n; i++)
        {
            for(int j=0;j<mp[i].size();j++)
            {
                int v = mp[i][j];
                if(belong[v]!=belong[i])
                {
                    nn[belong[i]].pb(belong[v]);
                }
            }
        }
        int cnt = 0,ans;
        for(int i=1; i<=scc; i++)
        {
            if(nn[i].size()==0)
            {
                cnt++;
                ans = i;
            }
        }
        if(cnt==1)
        {
            printf("%d
    ",num[ans]);
        }
        else printf("0
    ");
    
    }
    int main(){
        while(~scanf("%d%d", &n, &m))
        {
            init();
            for(int i=1; i<=m; i++)
            {
                int u,v;
                scanf("%d%d", &u, &v);
                mp[u].pb(v);
            }
            for(int i=1; i<=n; i++)
            {
                if(dfn[i]==0)tarjan(i);
            }
            solve();   
        }
        return 0;
    }
  • 相关阅读:
    Leetcode——栈和队列(3)
    Leetcode——栈和队列(2)
    java——面试题 基础(上)
    Leetcode——栈和队列(1)
    LeetCode——动态规划整理(2)
    LeetCode——动态规划整理(1)
    计算机网络——数据中心(下)
    计算机网络——数据中心(上)
    计算机网络——HTTP(下)
    计算机网络——HTTP(上)
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/9067787.html
Copyright © 2011-2022 走看看