题意:问有多少只牛被所有的牛膜拜;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; }