DFN-LOW算法---割点、桥、强连通分量
无向图:割顶:
Program gedian; var n,m,time,x,y,sum,t,i :longint; link,next,endv,dfn,low :array[1..10000] of longint; b :array[1..10000] of boolean; Procedure insert(u,v:longint); begin inc(t); endv[t]:=v; next[t]:=link[u]; link[u]:=t; end; Procedure DFS(x,fa:longint); var p,v:longint; begin inc(time); low[x]:=time; dfn[x]:=time; p:=link[x]; while p<>-1 do if endv[p]<>fa then begin v:=endv[p]; if dfn[v]=0 then begin if x=1 then inc(sum); DFS(v,x); if low[v]<low[x] then low[x]:=low[v]; if low[v]>=dfn[x] then b[x]:=true; end else if low[x]>dfn[v] then low[x]:=dfn[v]; p:=next[p]; end else p:=next[p]; end; begin readln(n,m); for i:=1 to n do link[i]:=-1; for i:=1 to m do begin readln(x,y); insert(x,y); insert(y,x); end; DFS(1,1); if sum>=2 then writeln(1); for i:=2 to n do if b[i] then writeln(i); end.
桥:
Program bridge; var next,link,endv,sta :array[1..100000] of longint; dfn,low :array[1..100000] of longint; b :array[1..100000] of boolean; n,m,i,x,y,t,time :longint; Procedure insert(u,v:longint); begin inc(t); sta[t]:=u; endv[t]:=v; next[t]:=link[u]; link[u]:=t; end; Procedure DFS(x,fa:longint); var p,v:longint; begin inc(time); dfn[x]:=time; low[x]:=time; p:=link[x]; while p<>-1 do if endv[p]<>fa then begin v:=endv[p]; if dfn[v]=0 then begin DFS(v,x); if low[v]<low[x] then low[x]:=low[v]; if low[v]=dfn[v] then b[p]:=true; end else if dfn[v]<low[x] then low[x]:=dfn[v]; p:=next[p]; end else p:=next[p]; end; begin readln(n,m); for i:=1 to n do link[i]:=-1; for i:=1 to m do begin readln(x,y); insert(x,y); insert(y,x); end; DFS(1,1); for i:=1 to t do if b[i] then writeln(sta[i],' ',endv[i]); end.
有向图:
强联通分量
Program tarjan; var link,next,endv :array[1..10000] of longint; dfn,low,stack,lab,view :array[1..10000] of longint; n,m,top,i,x,y,time,total :longint; Procedure insert(t,u,v:longint); begin endv[t]:=v; next[t]:=link[u]; link[u]:=t; end; Procedure DFS(x:longint); var p,v:longint; begin inc(time); dfn[x]:=time; low[x]:=time; inc(top); stack[top]:=x; view[x]:=1; p:=link[x]; while p<>-1 do begin v:=endv[p]; if view[v]=0 then DFS(v); if (view[v]<2) and (low[v]<low[x]) then low[x]:=low[v]; p:=next[p]; end; if dfn[x]=low[x] then begin inc(total); while stack[top]<>x do begin v:=stack[top]; view[v]:=2; lab[v]:=total; dec(top); end; lab[x]:=total; view[x]:=2; dec(top); end; end; begin readln(n,m); for i:=1 to n do link[i]:=-1; for i:=1 to m do begin readln(x,y); insert(i,x,y); end; for i:=1 to n do if dfn[i]=0 then DFS(i); for i:=1 to n do writeln(lab[i]); end.