POJ 2186Popular Cows(Tarjan)

来源:互联网 发布:与明星合照软件 编辑:程序博客网 时间:2024/04/27 05:36

题意:问有多少只牛被所有的牛膜拜;A膜拜B,B膜拜C ,则A膜拜C ,

用Tarjan 缩点,求一个出度为0的点。包含原来点的个数。简单题。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>#include <stack>using namespace std;const int N = 10009;const int M = 50009;int n,m;struct LT{    int nex,to;} L[M];int F[N],cnt;void add(int f,int t){    L[cnt].nex = F[f];    L[cnt].to = t;    F[f] =cnt++;}int dfn[N],low[N],post[N],col[N],ind,color;stack<int> S;void tarjan(int k){    dfn[k] = low[k] = ind++;    S.push(k);    post[k] = 1;    for(int i=F[k];i;i=L[i].nex)    {        int to = L[i].to;        if(!dfn[to])        {            tarjan(to);            low[k] = min(low[k],low[to]);        }        else if(post[to]&&low[k]>dfn[to])        low[k] = dfn[to];    }    if(low[k] == dfn[k])    {        int i;color++;        for(i=S.top(),S.pop();i!=k;i=S.top(),S.pop())        {            post[i] = false;col[i] = color;        }        post[k] = false;col[k] = color;    }}int out[N];int main(){    freopen("in.txt","r",stdin);    scanf("%d%d",&n,&m);    int f,t;cnt = 1;    for(int i=0;i<m;i++)    scanf("%d%d",&f,&t),add(f,t);    ind = 1;    for(int i=1;i<=n;i++)    if(!dfn[i]) tarjan(i);    if(color==1)    {        printf("%d\n",n);        return 0;    }    for(int i=1;i<=n;i++)    {        for(int j=F[i];j;j=L[j].nex)        if(col[i]!=col[L[j].to])        {            out[col[i]] = 1;        }    }    int ans =0,c;    for(int i=1;i<=color;i++)    if(!out[i]) ans++,c=i;    if(ans>1)    {        printf("0\n"); return 0;    }    ans = 0;    for(int i=1;i<=n;i++)    if(col[i]==c) ans++;    printf("%d\n",ans);    return 0;}


原创粉丝点击