P2341 [USACO03FALL][HAOI2006]受欢迎的牛 (tarjan缩点,拓扑)
#include<iostream> #include<cstring> using namespace std; const int maxn=50010; int head[maxn],cnt; int dfn[maxn],low[maxn],tot,stack[maxn],idx,visit[maxn]; int num,color[maxn],cow[maxn]; int out[maxn],ans,res; struct node { int to; int next; }edge[maxn]; void add(int u,int v) { edge[++cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; } void tarjan(int x) { dfn[x]=low[x]=++tot; stack[++idx]=x; visit[x]=1; for(int i=head[x];i;i=edge[i].next) { if(!dfn[edge[i].to]) { tarjan(edge[i].to); low[x]=min(low[x],low[edge[i].to]); } else if(visit[edge[i].to]) { low[x]=min(low[x],dfn[edge[i].to]); } } if(dfn[x]==low[x]) { ++num; do { visit[stack[idx]]=0; color[stack[idx]]=num; cow[num]++; idx--; }while(x!=stack[idx+1]); } return; } int main() { int n,m; cin>>n>>m; int u,v; for(int i=1;i<=m;i++) { cin>>u>>v; add(u,v); } for(int i=1;i<=n;i++) { if(!dfn[i]) { tarjan(i); } } for(int i=1;i<=n;i++) { for(int j=head[i];j;j=edge[j].next) { if(color[edge[j].to]!=color[i]) { out[color[i]]++; } } } for(int i=1;i<=num;i++) { if(!out[i]) { ans=cow[i]; res++; } } if(res==1) { cout<<ans<<endl; } else { cout<<0<<endl; } return 0; }