内容目录
题目大意:给有向图G,求图G中有多少点能从所有起点到达
暴搜必T,故本题需要用Tarjen求有向图的强连通分量。
缩点后得DAG(若有环则属同一强连通分量)
由于无环,故这图为树或树的森林
先判断图是否连通,若为森林则无解
否则,判定每个SSC是否有连出的边(由于图无环,故连出的边上的点无法回去)
答案即为出度为0的连通分量上的点
如果不止一个这样的点,则不同的点无法互相到达
Program P2186; const maxn=10000; maxm=50000; var head,edge,tail:array[1..maxm] of longint; sizeedge:longint; n,m,i,j,x,y:longint; ssc,c,dfs,low,outdegree,stack:array[1..maxn] of longint; time,size:longint; totssc:longint; procedure addedge(u,v:longint); begin inc(sizeedge); edge[sizeedge]:=v; tail[sizeedge]:=head[u]; head[u]:=sizeedge; end; function min(a,b:longint):longint; begin if a<b then exit(a) else exit(b); end; procedure tarjen(k,father:longint); var i,j,p:longint; begin inc(time); dfs[k]:=time;low[k]:=time; c[k]:=1; inc(size);stack[size]:=k; p:=head[k]; while (p<>0) do begin i:=edge[p]; if (dfs[k]>dfs[i]) then begin if c[i]=0 then begin tarjen(i,k); low[k]:=min(low[k],low[i]); end else if c[i]=1 then low[k]:=min(low[k],dfs[i]); end; p:=tail[p]; end; if low[k]=dfs[k] then begin inc(totssc); repeat i:=stack[size]; dec(size); c[i]:=2; ssc[i]:=totssc; until ((size=0) or (i=k)); end; end; function main:longint; var i,j,tot,node,p:longint; begin fillchar(dfs,sizeof(dfs),0); fillchar(low,sizeof(low),0); fillchar(c,sizeof(c),0); fillchar(outdegree,sizeof(outdegree),0); time:=0; totssc:=0; for i:=1 to n do if (dfs[i]=0) then begin fillchar(stack,sizeof(stack),0); size:=0; tarjen(i,0); end; for i:=1 to n do begin p:=head[i]; while (p<>0) do begin j:=edge[p]; if (ssc[i]<>ssc[j]) then begin inc(outdegree[ssc[i]]); end; p:=tail[p]; end; end; node:=0; for i:=1 to totssc do if outdegree[i]=0 then begin if node<>0 then exit(0); node:=i; end; tot:=0; for i:=1 to n do if ssc[i]=node then inc(tot); exit(tot); end; begin sizeedge:=0; fillchar(head,sizeof(head),0); fillchar(tail,sizeof(tail),0); fillchar(edge,sizeof(edge),0); read(n,m); for i:=1 to m do begin read(x,y); addedge(x,y); end; writeln(main); end.