BZOJ 1051:[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
分析:
求出图的强连通分量并缩点,再检查出度为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 readln(n,m); t:=0; for i:=1 to m do begin readln(x,y); 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.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步