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