tarjan求強連通分量

2022-03-05 00:59:58 字數 1750 閱讀 5816

**自

一.演算法簡介

我們定義:

如果兩個頂點可以相互通達,則稱兩個頂點強連通(strongly connected)。如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。有向圖的極大強連通子圖,稱為強連通分量(strongly connected components)。

例如:在上圖中, ,  ,   三個區域可以相互連通,稱為這個圖的強連通分量。

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

再tarjan演算法中,有如下定義。

dfn[ i ] : 在dfs中該節點被搜尋的次序(時間戳)

low[ i ] : 為i或i的子樹能夠追溯到的最早的棧中節點的次序號

當dfn[ i ]==low[ i ]時,為i或i的子樹可以構成乙個強連通分量。

二.演算法圖示

以1為tarjan 演算法的起始點,如圖

順次dfs搜到節點6

回溯時發現low[ 5 ]==dfn[ 5 ] ,  low[ 6 ]==dfn[ 6 ] ,則 , 為兩個強連通分量。回溯至3節點,拓展節點4.

拓展節點1 , 發現1再棧中更新low[ 4 ],low[ 3 ] 的值為1

回溯節點1,拓展節點2

自此,tarjan algorithm 結束, ,  ,   為圖中的三個強連通分量。

不難發現,tarjan algorithm 的時間複雜度為o(e+v).

#include#include

using

namespace

std;

#define maxn 1005

struct

edgeedge[maxn*maxn];

int fi[maxn],se,col[maxn],sc,sta[maxn],top,dfn[maxn],low[maxn],df;//

col為每個點屬於的強連通分量,sta為模擬的棧;

bool

vis[maxn];

inline

void add_edge(int u,int

v)void tarjan(int

x)

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

top--;

}}int

main()

強連通分量 tarjan求強連通分量

雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...

Tarjan求強連通分量

強連通分量 有向圖強連通分量 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,則稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,成為強連通分量 strongly connected components 直...

tarjan求強連通分量

tarjan求強連通分量 我們知道,在有向圖g中,如果任意兩個頂點都是連通的 所謂連通就是兩個頂點都能互相到達 那麼這個圖就是強連通圖。非強連通圖的極大強連通子圖,被稱為強連通分量。那麼什麼是極大強連通子圖呢?舉個例子幫助理解一下 例如下面圖一所示,其中子圖就是乙個極大強連通子圖,子圖也是乙個極大強...