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;
    }
  • 相关阅读:
    搜索回车跳转页面
    登录验证码
    【排序算法】排序算法之插入排序
    PAT 乙级 1044 火星数字 (20 分)
    PAT 甲级 1035 Password (20 分)
    PAT 甲级 1041 Be Unique (20 分)
    PAT 甲级 1054 The Dominant Color (20 分)
    PAT 甲级 1027 Colors in Mars (20 分)
    PAT 甲级 1083 List Grades (25 分)
    PAT 甲级 1005 Spell It Right (20 分)
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/9067787.html
Copyright © 2011-2022 走看看