Tarjan演算法模板

2021-08-21 12:45:35 字數 1699 閱讀 3074

一、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];//belong陣列的值是1-scc

//dfn[]作為這個點搜尋的次序編號(時間戳),簡單來說就是 第幾個被搜尋到的。%每個點的時間戳都不一樣%。

//作為每個點在這顆樹中的,最小的子樹的根,每次保證最小,like它的父親結點的時間戳這種感覺。如果它自己的low[]最小,那這個點就應該從新分配,變成這個強連通分量子樹的根節點

int index,top;

int scc;//強連通分量的個數

bool instack[maxn];

int num[maxn];//各個強連通分量包含的點個數,陣列編號1-scc

void addegde(int u,int v)

void tarjan(int u)//

else

if(instack[v]&&low[u]>dfn[v])

low[u]=dfn[v];

}if(low[u]==dfn[u])//每次找到乙個新點,這個點low[]=dfn[]。

while(v!=u);

}}void solve(int n)

void init()

二、arjan(無向圖)模板

//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];//belong陣列的值是1-scc

//dfn[]作為這個點搜尋的次序編號(時間戳),簡單來說就是 第幾個被搜尋到的。%每個點的時間戳都不一樣%。

//作為每個點在這顆樹中的,最小的子樹的根,每次保證最小,like它的父親結點的時間戳這種感覺。如果它自己的low[]最小,那這個點就應該從新分配,變成這個強連通分量子樹的根節點

int index,top;

int scc;//強連通分量的個數

bool instack[maxn];

int num[maxn];//各個強連通分量包含的點個數,陣列編號1-scc

void addegde(int u,int v)

void tarjan(int u,int pre)//本題是無向圖,所以構造強連通分量為乙個點的時候,不能又回到自身

else

if(instack[v]&&low[u]>dfn[v])

low[u]=dfn[v];

}if(low[u]==dfn[u])//每次找到乙個新點,這個點low[]=dfn[]。

while(v!=u);

}}void solve(int n)

void init()

想要詳細理解tarjan這裡

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演算法把這個圖的子圖 在這個子圖內,任意兩個點可以相互到達,極大的子圖 縮成乙個點,相當於化簡 怎樣去做 從乙個點開始遍歷它能走到的下乙個點...