求出强联通分量之后判断出度为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.
时间: 2024-10-06 23:41:42