首页 > 代码库 > HAOI2006受欢迎的牛(强联通分量)

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.