HAOI2006受欢迎的牛
求出强联通分量之后判断出度为0的点有几个,有1个就输出这个分量的点的数目,否则输出0;
var i,j,n,m,x,y,ans1,ans2,t,cnt,top:longint; head,next,go,sta,inp:array[0..50010] of longint; low,dfn,scc,s:array[0..10000] of longint; flag:array[0..10000] of boolean; function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end; procedure dfs(k:longint); var i,v,x:longint; begin inc(t);dfn[k]:=t;low[k]:=t; inc(top);sta[top]:=k; i:=head[k]; while i<>0 do begin v:=go[i]; if dfn[v]=0 then begin dfs(v); low[k]:=min(low[k],low[v]); end else if scc[v]=0 then low[k]:=min(low[k],dfn[v]); i:=next[i]; end; if low[k]=dfn[k] then begin inc(cnt); repeat x:=sta[top];inc(s[cnt]); dec(top); scc[x]:=cnt; if x=k then break; until false; end; end; procedure init; begin readln(n,m); for i:=1 to m do begin readln(x,y); go[i]:=y;next[i]:=head[x];head[x]:=i; end; for i:=1 to n do if dfn[i]=0 then dfs(i); end; procedure main; begin fillchar(flag,sizeof(flag),true); for i:=1 to n do begin j:=head[i]; while j<>0 do begin x:=go[j]; if scc[x]<>scc[i] then flag[scc[i]]:=false; j:=next[j]; end; end; for i:=1 to cnt do if flag[i] then begin inc(ans1);ans2:=s[i]; end; if ans1=1 then writeln(ans2) else writeln(0); end; begin init; main; end.