# BZOJ 1051：[HAOI2006]受欢迎的牛（强连通分量）

受欢迎的牛
Description

Input

Output

Sample Input
3 3
1 2
2 1
2 3
Sample Output
1
HINT
100%的数据N<=10000,M<=50000

求出图的强连通分量并缩点，再检查出度为0点的个数，若为不为1，说明无解，若个数为1，输出那个点代表的强连通分量点的个数。

program cow;
type
point=^node;
node=record
data:longint;
next:point;
end;
var
a,b:array[0..10000]of point;
f,q,c:array[0..10000]of longint;
w,g:array[0..10000]of boolean;
n,i,m,s,t,x,y,v:longint; p:point;
procedure dfs1(x:longint);
var p:point;
begin
g[x]:=true; new(p); p:=a[x];
while p<>nil do
begin
if g[p^.data]=false then dfs1(p^.data); p:=p^.next;
end;
t:=t+1; q[t]:=x;
end;
procedure dfs2(x,y:longint);
var p:point;
begin
g[x]:=true; new(p); p:=b[x];
while p<>nil do
begin
if g[p^.data]=false then dfs2(p^.data,y); p:=p^.next;
end;
s:=s+1; f[x]:=y;
end;
begin
for i:=1 to m do
begin
new(p);  p^.data:=y; p^.next:=a[x]; a[x]:=p;
new(p);  p^.data:=x; p^.next:=b[y]; b[y]:=p;
end;
for i:=1 to n do if g[i]=false then dfs1(i);
fillchar(g,sizeof(g),false);
for i:=t downto 1 do
begin
x:=q[i];
if g[x]=false then
begin
s:=0; dfs2(x,x);c[x]:=c[x]+s;
end;
end;
fillchar(w,sizeof(w),1);
for i:=1 to n do
begin
new(p);p:=a[i]; v:=0;
while p<>nil do
begin
if f[i]<>f[p^.data] then begin v:=1;break;  end;  p:=p^.next;
end;
if v=1 then w[f[i]]:=false;
end;
for i:=1 to n do if f[i]<>i then w[i]:=false;s:=0;
for i:=1 to n do
if w[i]=true then begin inc(s); t:=c[i]; end;
if s=1 then writeln(t) else writeln(-1);
end.
View Code

posted @ 2015-11-05 13:32  QTY_YTQ  阅读(145)  评论(0编辑  收藏