题意:给出m个数对(a,b) 表示a牛认为b牛受欢迎,如果a牛认为b牛受欢迎,b牛认为c牛受欢迎,则a牛也认为c牛受欢迎。找到被所有牛认为是受欢迎的牛的个数(自己不用认为自己受欢迎= =)
我们很容易发现“认为受欢迎”是具有传递性的
那么,对于a牛认为b牛受欢迎我们就建一条a指向b的有向边
然后我们发现,对于每一个强连通分量,他们是互相认为受欢迎的=。=
那么我们所点重新构图后就形成了一个DAG
重新构图后,
如果有且仅有一个“点”的出度为0那么答案就是这个“点”的size
否则输出0
var
n,m,a,b,l,time,top,t,ans:longint;
last :array[0..10010] of longint;
size,chu :array[0..20010] of longint;
dfn,low,z,belong :array[0..10010] of longint;
vis :array[0..20010] of boolean;
i :longint;
pre,other :array[0..50010] of longint;
function min(a,b:longint):longint;
begin
if a<b then exit(a) else exit(b);
end;
procedure connect(x,y:longint);
begin
inc(l);
pre[l]:=last[x];
last[x]:=l;
other[l]:=y;
end;
procedure dfs(x:longint);
var
p,q,cur:longint;
begin
inc(time);
low[x]:=time;
dfn[x]:=time;
inc(top);
z[top]:=x;
vis[x]:=true;
//
q:=last[x];
while (q<>0) do
begin
p:=other[q];
if dfn[p]=0 then
begin
dfs(p);
low[x]:=min(low[x],low[p]);
end else
if vis[p] then low[x]:=min(low[x],dfn[p]);
q:=pre[q];
end;
//
if (low[x]=dfn[x]) then
begin
cur:=-1;
while (cur<>x) do
begin
cur:=z[top];
dec(top);
vis[cur]:=false;
belong[cur]:=x+n;
inc(size[belong[cur]]);
end;
end;
end;
procedure rebuild;
var
p,q:longint;
i:longint;
begin
for i:=1 to n do
begin
q:=last[i];
while (q<>0) do
begin
p:=other[q];
if (belong[i]<>belong[p]) then inc(chu[belong[i]]);
q:=pre[q];
end;
end;
end;
begin
read(n,m);
for i:=1 to m do
begin
read(a,b);
connect(a,b);
end;
//
for i:=1 to n do if dfn[i]=0 then dfs(i);
//
rebuild;
t:=0;
for i:=n+1 to n*2 do vis[i]:=false;
for i:=1 to n do
if (chu[belong[i]]=0) and not vis[belong[i]] then
begin
inc(t);
ans:=size[belong[i]];
vis[belong[i]]:=true;
end;
//
if (t=1) then writeln(ans) else writeln(0);
end.
——by Eirlys