談談Tarjan演算法

2022-05-16 11:31:23 字數 1890 閱讀 3249

tarjan演算法是一系列用dfs解決圖論問題的演算法,由美國計算機科學家tarjan提出。

首先先分析有向圖中tarjan演算法的應用:求有向圖強連通分量。

首先介紹一些在tarjan演算法中特殊陣列的定義,這個定義怎麼提出來的咱也不知道,咱也不敢問。

乙個是dfn陣列,表示dfs搜尋的時間戳,也就是第幾個搜尋到這個點。另乙個是low陣列,記錄的是某個點經過若干條樹邊和至多一條非樹邊到達的最小的dfn。

再說說什麼是非樹邊,樹邊。樹邊感性理解就是dfs會得到一棵dfs搜尋樹,然後這棵搜尋樹上的邊就是樹邊,對應的不在樹上的就是非樹邊。而非樹邊又分兩種,返祖邊和橫叉邊。好吧其實非樹邊具體是啥沒用2333。

那麼感性理解一下我們大致可以得到乙個式子:low[u] = min(low[v],low[u]),u表示當前節點,v表示這個節點能到的節點。顯然對於節點u,如果它的子節點v的low更小,換句話說v可以到達乙個dfn更小的點,那麼u同樣可以經過u,v之間的樹邊到達那個dfn更小的點。

那如果某個點經過一頓操作,最後low值和dfn值仍相等,說明這個點到不了之前的點了,那這個點就是乙個強連通分量的根。如果我們維護乙個棧,把每個搜到的點放進去,如果搜完發現乙個點low和dfn相等就把這個點以及棧裡在它上面的點彈出去。因為這個點上面的點都是這個點可以到的點,都屬於同乙個強連通分量。

好的演算法就結束了。

1 #include2 #include3 #include4 #include5 #include6 #include7

#define n 10010

8#define m 100010

9#define b printf("break\n");

10using

namespace

std;

11int head[n],nxt[m],to[m],val[n],in

[n];

12int

n,m,cnt;

13void add(int u,int

v)14

21void

reset()

2229

intdfn[n],low[n],tim;

30int

scc[n];

31bool

vis[n];

32 stacks;

33void tarjan(int

u)34

46else

if(vis[v])

4750}51

if(dfn[u] ==low[u])

5260

s.pop();

61 scc[u] =u;

62 vis[u] = 0;63

}64}65

intdis[n];

66int

topo_sort()

6776}77

while

(q.size())

7888}89

int ans = 0;90

for(int i = 1;i <= n;i++) ans =max(ans,dis[i]);

91return

ans;92}

93int

from

[m],tto[m];

94int

main()

95101

for(int i = 1;i <= m;i++)

102106

for(int i = 1;i <= n;i++)

107110

reset();

111for(int i = 1;i <= m;i++)

112118

}119 printf("%d"

,topo_sort());

120 }

有向圖縮點

tarjan演算法詳解

參考 tarjan演算法在強連通分量分離中運用很廣,書寫簡單,並且可以拓展到圖的割點,割邊上,十分強大 具體思路 令dfn u 表示當前點的時間戳 low u 表示當前點所能到達的點的時間戳中最小的乙個 到達點u時,將其入棧 拓展點u後代 當且僅當dfn u low u 時,棧頂元素全部出棧,此時出...

Tarjan 演算法筆記

tarjan演算法 tarjan演算法屬於圖論中的乙個演算法,主要用來求乙個圖中的強連通分量,之後就可以做很多事,比如說縮點 求雙聯通分支等。強連通 在乙個有向圖中,對於幾個點,如果它們能夠互相到達,那麼稱它們強連通。強連通分量 可以這樣理解 把乙個圖里的點分成幾坨,每坨中的點都能夠互相到達 他們強...

Tarjan演算法詳解

tarjan演算法的用途 1.求橋和割點 2.求點和邊的雙連通分量 3.求強連通 targan演算法的流程 利用dfs來遍歷圖來構建一種數型的結構 tarjan演算法的兩個核心陣列 1 對於第一種用途 tarjan演算法原理 我們從1開始遍歷,發現6,5,4的low不小於dfn 3 故3為割點 即4...