bzoj1051 [HAOI2006]受欢迎的牛

Description

  每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
牛被所有的牛认为是受欢迎的。
 

Input

  第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
能出现多个A,B)
 

Output

  一个数,即有多少头牛被所有的牛认为是受欢迎的。

 

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1
 

HINT

100%的数据N<=10000,M<=50000
 
 
 
先tarjan将强连通分量缩点,如果出度为0的强连通分量超过1个,输出0,如果只有一个,输出那个的大小就行了。
一开始在洛谷无限WA,然后发现时把dfs时的low初值写成k了,实际上是cnt。
 1 program rrr(input,output);
 2 type
 3   etype=record
 4      t,next:longint;
 5   end;
 6 var
 7    e:array[0..50050]of etype;
 8    a,q,belong,siz,dfn,low:array[0..10010]of longint;
 9    inq,c:array[0..10010]of boolean;
10    n,m,i,j,cnt,top,tot,x,y:longint;
11 procedure add(x,y:longint);
12 begin
13    inc(cnt);e[cnt].t:=y;e[cnt].next:=a[x];a[x]:=cnt;
14 end;
15 procedure tarjan(k:longint);
16 var
17   i:longint;
18 begin
19   inc(cnt);dfn[k]:=cnt;low[k]:=cnt;
20   inq[k]:=true;inc(top);q[top]:=k;
21   i:=a[k];
22   while i<>0 do
23      begin
24         if dfn[e[i].t]=0 then begin tarjan(e[i].t);if low[e[i].t]<low[k] then low[k]:=low[e[i].t]; end
25         else if inq[e[i].t] and (dfn[e[i].t]<low[k]) then low[k]:=dfn[e[i].t];
26         i:=e[i].next;
27      end;
28    if dfn[k]=low[k] then
29       begin
30          inc(tot);
31          while q[top]<>k do
32             begin
33                belong[q[top]]:=tot;inc(siz[tot]);
34                inq[q[top]]:=false;dec(top);
35             end;
36          belong[k]:=tot;inc(siz[tot]);dec(top);inq[k]:=false;
37       end;
38 end;
39 begin
40    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
41    readln(n,m);
42    fillchar(a,sizeof(a),0);cnt:=0;
43    for i:=1 to m do begin readln(x,y);add(x,y); end;
44    cnt:=0;fillchar(dfn,sizeof(dfn),0);
45    top:=0;fillchar(inq,sizeof(inq),false);
46    tot:=0;fillchar(siz,sizeof(siz),0);
47    for i:=1 to n do if dfn[i]=0 then tarjan(i);
48    fillchar(c,sizeof(c),false);
49    for i:=1 to n do
50       if not c[belong[i]] then
51          begin
52             j:=a[i];
53             while j<>0 do
54                begin
55                   if belong[i]<>belong[e[j].t] then begin c[belong[i]]:=true;break; end;
56                   j:=e[j].next;
57                end;
58          end;
59    j:=0;
60    for i:=1 to tot do if not c[i] then begin if j>0 then begin j:=0;break; end;j:=i; end;
61    if j=0 then write(0) else write(siz[j]);
62    close(input);close(output);
63 end.

 

posted @ 2017-04-03 12:00  Klaier  阅读(177)  评论(0编辑  收藏  举报