今天,我們要**的就是——tarjan演算法。
tarjan演算法的主要作用便是求一張無向圖中的強連通分量,並且用它縮點,把原本乙個雜亂無章的有向圖轉化為一張dag(有向無環圖),以便解決之後的問題。
首先,我們在原圖上跑一遍dfs,然後會發現三種邊:
1、正常邊:嗯,顧名思義就是連線祖先和兒子節點的邊。
2、橫叉邊:連線到了已經彈出的節點的邊(也能叫它小三邊)。
3、返祖邊:從兒子節點連到祖先的邊。
那麼通過進一步的觀察我們可以發現:返祖邊可能產生強連通分量,而橫叉邊不能。(如下圖所示)
dfs遍歷之後即為:
這時,我們發現上圖出現了一種「大圈包小圈」的情況(和)那麼我們應該如何處理才能做到當出現上圖情況時只計算最大的那個強連通分量呢?
我們可以開兩個陣列:
dfn[i]:記錄當遍歷到節點i時是第幾次dfs。
low[i]:記錄以i為根的子樹中能夠連線到當前棧中最小的dfn值(也就是最上面的節點)。
然後每次取最小的low[i]就可以了。
emmmmmmmmmmm,那就上**吧。(pascal黨的福利哦)
varvis:
array[1..100000]of
boolean;
stack,dfn,low,head,next,vet,blong,belong:
array[1..100000]of
longint;
tot,time,top,x,y,i,n,m,point:longint;
function
min(a,b:longint):longint;
begin
if athen exit(a) else
exit(b);
end;
procedure
add(x,y:longint);
begin
inc(tot);
next[tot]:=head[x];
vet[tot]:=y;
head[x]:=tot;
end;
procedure
tarjan(u:longint);
vari,v:longint;
begin
inc(time);
dfn[u]:=time; low[u]:=time;
inc(top);
stack[top]:=u; vis[u]:=true;
i:=head[u];
while i<>0
dobegin
v:=vet[i];
if vis[v] then low[u]:=min(dfn[v],low[u])
else
if dfn[v]=0
then
begin
tarjan(v);
low[u]:=min(low[v],low[u]);
end;
i:=next[i];
end;
if dfn[u]=low[u] then
begin
inc(point); belong[u]:=point;
while stack[top]<>u do
begin
belong[stack[top]]:=point;
vis[stack[top]]:=false;
dec(top);
end;
vis[u]:=false; dec(top)
end;end
;procedure
shrink_point;
varu,i,v:longint;
begin
for u:=1
to n do
begin
i:=head[u];
while i<>0
dobegin
v:=vet[i];
if belong[i]<>belong[v] then
add(belong[u],belong[v]);
i:=next[i];
end;
end;end
;begin
read(n,m);
point:=n;
for i:=1
to m do
begin
read(x,y);
add(x,y);
end;
for i:=1
to n do
if dfn[i]=0
then
tarjan(i);
shrink_point;
end.
《學習筆記》 tarjan 求強連通分量
時間複雜度 o n m dfs 求解。定義 dfn n 為n當前的時間戳,low n 為n最早能追溯到的時間戳,可知 1 for int i first n i i next i 28 else 9if instack rode i t low n min low n dfn rode i t 10...
Tarjan演算法的學習 求強連通分量
1 相關概念 強連通圖 在乙個強連通圖中,任意兩個點都通過一定路徑互相連通。強連通分量 在乙個非強連通圖中極大的強連通子圖就是該圖的強連通分量。2 偽 algorithm tarjan is input 圖 g v,e output 以所在的強連通分量劃分的頂點集 index 0 s empty 置...
tarjan 演算法 求強連通分量)
全網最詳細tarjan演算法講解,我不敢說別的。反正其他tarjan演算法講解,我看了半天才看懂。我寫的這個,讀完一遍,發現原來tarjan這麼簡單!tarjan演算法,乙個關於 圖的聯通性的神奇演算法。基於dfs 迪法師 演算法,深度優先搜尋一張有向圖。注意!是有向圖。根據樹,堆疊,打標記等種種神...