強連通分量 Tarjan演算法

2021-09-11 06:04:37 字數 1902 閱讀 3441

有向圖強連通分量:在有向圖g中,如果兩個頂點vi,vj間(vi>vj)有一條從vi到vj的有向路徑,同時還有一條從vj到vi的有向路徑,則稱兩個頂點強連通。如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。有向圖的極大強連通子圖,稱為強連通分量。

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

定義 dfn[u] 為節點u搜尋的次序編號(時間戳) ,low[u]  為u 或u的子樹能夠追溯到的最早的棧中節點的次序號 . 

當dfn[u] = low[u]  時 , 以 u 為根的搜尋子樹上所有節點時乙個強連通分量 , 偽** : 

演算法流程 :

模板 :  

鄰接表存圖

#include #include #include #include #include #include #include #include using namespace std;

const int max = 10010 ;

vector g[max] ;

int color[max] ;

int dfn[max] ; // 表示dfs時第幾個被搜到的

int low[max] ; // 表示這個點以及其子孫節點連的所有點中dfn最小的值

int stack[max] ; //當前所有可能能構成強連通分量的點

int vis[max] ; // 標記

int cnt[max] ;

int deep ,top , n , m, sum , ans ;

void tarjan(int u )

} cout鏈式前向星 

#include #include #include #include #include #include #include #include #include using namespace std;

const int max = 100100 ;

int n , m , idx ;

int cnt ,bcnt ;

int head[max] ;

int vis[max] ;

int dfn[max] ,low[max] ;

int belong[max] ;

stacks ;

struct edgee[max] ;

void add(int u , int v)

void tarjan(int u )

else

} }if(dfn[u] == low[u])while(u!=v) ; }

}int main()

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

}// cout<1)

} cout<

return 0;

}

強連通分量Tarjan演算法

o v e 通常的tarjan寫法是有個dfn陣列跟乙個instack陣列,我精簡了下 把這兩個陣列都刪去了,用更簡便的寫法代替,也省了空間。int low maxn 記錄這棵樹能到達的最早祖先 其實不一定是最早,但不影響使用 int time 時間戳 int num 連通分量的個數 int bel...

強連通分量 tarjan演算法

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

強連通分量 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 圖的鄰...