tarjan算法详解

参考:http://blog.sina.com.cn/s/blog_69a101130100k1cm.html

tarjan算法在强连通分量分离中运用很广,书写简单,并且可以拓展到图的割点,割边上,十分强大微笑

具体思路:令dfn【u】表示当前点的时间戳

                         low【u】表示当前点所能到达的点的时间戳中最小的一个

                         到达点u时,将其入栈

                        拓展点u后代

                     当且仅当dfn【u】=low【u】时,栈顶元素全部出栈,此时出栈的元素即为一个强连通分量。

我写的程序:

type
  point=^node;
  node=record
        v:longint;
        next:point;
       end;
var
  instack:array[0..100000]of boolean;
  time,top,n,ans,i,x,y:longint;
  low,stack,dfn:array[0..100000]of longint;
  a:array[0..100000]of point;
function min(a,b:longint):longint;
begin
  if a<b then exit(a);
  exit(b);
end;
procedure tarjan(u:longint);
var
  p:point;
  v:longint;
begin
  time:=time+1;
  low[u]:=time;dfn[u]:=time;
  stack[top]:=u;
  instack[u]:=true;
  top:=top+1;
  p:=a[u];
  while p<>nil do
   begin
     if dfn[p^.v]=0 then
      begin
        tarjan(p^.v);
        low[u]:=min(low[u],low[p^.v]);
      end
     else if instack[p^.v] then low[u]:=min(low[u],dfn[p^.v]);
     p:=p^.next;
   end;
  if low[u]=dfn[u] then
   begin
     ans:=ans+1;
     writeln('Case #',ans,':');
     repeat
       top:=top-1;v:=stack[top];
       write(v,' ');
       instack[v]:=false;
     until u=v;
     writeln;
   end;
end;
procedure build(x,y:longint);
var
  p:point;
begin
  new(p);
  p^.v:=y;
  p^.next:=a[x];
  a[x]:=p;
end;
begin
  readln(n);
  top:=1;
  for i:=1 to n do
   begin
     readLn(x,y);
     build(x,y);
   end;
  tarjan(1);
end.


你可能感兴趣的:(tarjan算法详解)