演算法模板 tarjan

2022-10-09 13:18:08 字數 866 閱讀 1106

tarjan演算法基於深度優先搜尋, 每個強連通分量為搜尋樹中的一棵子樹. 搜尋時, 把當前搜尋樹中未處理的結點加入堆疊, 回溯時就可判斷棧頂到棧中的結點是否為乙個強連通分量.

dfn[u]: 記錄結點u在dfs過程中被遍歷到的次序號(時間戳).

對於一棵dfs樹, 對於原圖中的非樹邊, 為便於描述, 定義:

前向邊: 祖先->兒子的邊.

後向邊: 兒子->祖先的邊.

橫叉邊: 沒有祖先兒子關係的邊(注意橫叉邊

只會往dfn減小的方向連線).

low[u]: 記錄結點u或u的子樹能夠追溯到的dfn最小的值(棧中標號的最小點)

由定義, 顯然有:

⚫ 若(u,v)為樹邊, low[u] = min;

⚫ 若(u,v)是指向棧中結點的後向邊, low[u] = dfn(v).

定理: 當dfn[u] = low[u]時, 以u為根的搜尋子樹上所有結點構成乙個強連通分量.

證明: dfn[u]表示u點被dfs到的時間, low[u]表示u和u所有的子樹所能到達的點中dfn最小值.

dfn[u]=low[u], 這說明u點及u的子樹結點最多只有指向u點的邊, 而沒有指向u的祖先的邊了.

顯然, 遍歷過的結點從u出發又最終回到u形成乙個環, 即u點與它的子孫結點構成了強連通分量.

inline void paint(int x) 

void tarjan(int u)

else if (ins[v]) //後向邊(排除橫叉邊)

low[u] = min(low[u], dfn[v]);

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

paint(u);}}

Tarjan演算法模板

tarjan演算法是根據棧和dfs來實現。每個點有2個資料 dfn和low 結點1的dfn為1,low也為1,然後dfs到3,3的dfn為2,low為2,每次訪問乙個就dfn 當訪問的時候時是棧中結點時,就將low變為那個棧中結點的dfn,這樣可以保證low與dfn不相同。如果訪問不到棧中的結點,就...

Tarjan演算法 模板

只是下一下模板,如果還是沒有懂得原理的,可以看一下這位大牛的部落格 include include include include using namespace std const int maxn 1100 struct node edge maxn int head maxn int dfn ...

Tarjan演算法模板

一 tarjan有向圖的強連通 tarjan const int maxn 200100 const int maxm 500100 struct edgeedge maxm int head maxn tot int low maxn dfn maxn stack maxn belong maxn...