1051: [HAOI2006]受欢迎的牛
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2410 Solved: 1276
[Submit][Status]
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
Source
题解:这辈子第一次写tarjan强连通分量,才知道这玩意可以如此霸气地实现缩点。在这里面就是先缩完了点,然后重新弄出来一个图,然后看图上出度为0的点是否唯一,如果唯一,输出这个缩点上有多少个点,否则0.。。。么么哒(个人觉得百度百科的算法讲解说的挺好的,赞一个:传送门在此)
1 type 2 point=^node; 3 node=record 4 g:longint; 5 next:point; 6 end; 7 8 var 9 i,j,k,l,m,n,h,ans,t:longint; 10 a:array[0..100000] of point; 11 low,dfn,b,f,d,e:array[0..100000] of longint; 12 c:array[0..100000,1..2] of longint; 13 s,ss:array[0..100000] of boolean; 14 procedure add(x,y:longint);inline; 15 var p:point; 16 begin 17 new(p); 18 p^.g:=y; 19 p^.next:=a[x]; 20 a[x]:=p; 21 end; 22 function min(x,y:longint):longint;inline; 23 begin 24 if x<y then min:=x else min:=y; 25 end; 26 function max(x,y:longint):longint;inline; 27 begin 28 if x>y then max:=x else max:=y; 29 end; 30 31 procedure tarjan(x:longint); 32 var 33 i,j,k:longint;p:point; 34 begin 35 inc(h); 36 dfn[x]:=h; 37 low[x]:=h; 38 inc(t); 39 f[t]:=x; 40 s[x]:=true; 41 ss[x]:=true; 42 p:=a[x]; 43 while p<>nil do 44 begin 45 i:=p^.g; 46 if not s[i] then 47 begin 48 tarjan(i); 49 low[x]:=min(low[x],low[i]); 50 end 51 else if ss[i] then low[x]:=min(low[x],dfn[i]); 52 p:=p^.next; 53 end; 54 if dfn[x]=low[x] then 55 begin 56 inc(ans); 57 while f[t+1]<>x do 58 begin 59 ss[f[t]]:=false; 60 b[f[t]]:=ans; 61 dec(t); 62 end; 63 end; 64 end; 65 begin 66 fillchar(b,sizeof(b),0); 67 fillchar(s,sizeof(s),false); 68 fillchar(ss,sizeof(ss),false); 69 readln(n,m); 70 for i:=1 to n do a[i]:=nil; 71 for i:=1 to m do 72 begin 73 readln(c[i,1],c[i,2]); 74 add(c[i,1],c[i,2]); 75 end; 76 ans:=0; 77 tarjan(1); 78 for i:=1 to n do a[i]:=nil; 79 fillchar(d,sizeof(d),0); 80 fillchar(e,sizeof(e),0); 81 for i:=1 to n do inc(e[b[i]]); 82 for i:=1 to m do 83 if b[c[i,1]]<>b[c[i,2]] then inc(d[c[i,1]]); 84 j:=-1; 85 for i:=1 to ans do 86 begin 87 if d[i]=0 then 88 begin 89 if j=-1 then j:=i else 90 begin 91 writeln(0); 92 halt; 93 end; 94 end; 95 end; 96 if j=-1 then writeln(0) else writeln(e[j]); 97 readln; 98 end. 99
时间: 2024-10-24 04:44:33