Kosaraju演算法 強連通分量

2022-08-21 16:27:15 字數 1125 閱讀 1451

´有向圖的極大強連通子圖,稱為強連通分量。

´子圖指的是選取v的乙個子集v』,以及e當中所有滿足u,v∈v』的邊集e』所指代的圖.

´我們需要找出一幅有向圖當中的所有強連通分量。

´乙個最樸素的演算法:

´構造乙個傳遞閉包(也就是陣列aij表示i能否到達j),然後把aij=aji=1的節點置於同乙個強連通分量當中

´這個演算法的複雜度是o(n^3),優點是**複雜度小,缺點是速度太慢了

´這個演算法原理和上面的方法是類似的,如果a能到達b並且b能到達a,那麼a和b在同乙個強連通分量裡面。

´也可以等同於說,如果原圖與逆圖中a都能到達b,那麼a與b在同乙個強連通分量裡面。

´逆圖,指的是將原本有向圖的所有邊的方向變成相反,也就是說原本從a到b的邊變成從b到a。

´演算法流程有三步:

´對原圖進行dfs,求出每乙個節點的結束時間戳(離開這個節點時訪問了多少個節點);

´選擇結束時間戳最晚的節點,在逆圖中進行遍歷,刪除能遍歷到的節點,這些節點構成乙個強連通分量;

´如果還有頂點未刪除,重複第二步;

#include using

namespace

std;

const

int maxn=100000+15

;int

n,m;

vector

edge[maxn],rev[maxn];

int tim,rank[maxn],ref

[maxn];

bool

boo[maxn];

intcolor[maxn],tot;

int dfs1(int

now)

int dfs2(int

now)

intmain()

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

if (!boo[i]) dfs1(i);

for (int i=n;i>=1;i--)

if (color[ref[i]]==0

)

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

printf(

"%d

",color[i]);

return0;

}

強連通分量 Kosaraju演算法

求有向圖的強連通分量除了大家熟知的trajan,還可以用kosaraju 先說演算法流程 1,對原圖dfs一遍,並將出棧順序的逆序作為 偽拓撲序 2,對原圖夠構反向圖 3,按偽拓撲序在反向圖上dfs,新遍歷到的點都屬於同乙個強聯通分量。正確性證明 s在反向圖上dfs能夠遍歷到t,說明存在t到s的路徑...

強連通分量Kosaraju演算法

參考閱讀 如何理解kosaraju演算法?簡緻的回答 知乎 kosaraju演算法步驟 用dfs後序遍歷原圖的反轉圖,得到後序遍歷順序 用得到的後序遍歷順序對原圖dfs 實現 棧和圖的定義 const int maxv 100 定義棧 typedef struct snode stack 定義邊 t...

強連通分量 Kosaraju

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