tarjan演算法求強連通分支

2021-09-11 17:00:19 字數 1779 閱讀 1027

近期做資料結構課程設計,遇到了有向圖的強連通分支的問題,網上採用的是基於深度優先遍歷的tarjan演算法,在考了許多部落格後,還是有些迷,在思考了一番後,終於明白了,所以寫了這篇文章。

首先,明確以下幾點。

tarjan演算法基於深度優先遍歷。使用時,會用到兩個棧。乙個棧用於dfs,(如果是遞迴的tarjan演算法,是隱式地使用了系統堆疊);另乙個棧就是要儲存連通分支的資訊了,以下說的棧都是這個棧。

每個頂點有兩個屬性標記,dfn和low。

明確狀態

入棧,開始訪問乙個節點時,dfn == low == 當前是第幾個訪問到的序列號index

出棧,當dfn == low,且該節點沒有出邊時,得到了子樹的根,將其以及之後的(棧中)所有節點出棧,這樣便找到了乙個強連通分支

其他,當dfn != low,且該節點沒有出邊時,不做任何操作,只是回退到上乙個節點,繼續處理

演算法過程

對乙個頂點進行tarjan時,主要是對出邊的檢查

在進行tarjan(i)時,先後進行兩步操作:邊的檢查、low和dfn的檢查

先進行邊的檢查

如果有這樣的邊:i->j,有以下三種情況:

當i的出邊均訪問完後,檢查dfn和low

c++**

#include #include using namespace std;

int g[7][7]; //以鄰接矩陣表示6*6的圖,索引0不用

int index=0;

int dfn[7];

int low[7];

int c=1; //標記連通分支

stacktarjan; //儲存節點的棧

int component[7]; //記錄最終節點所屬的強連通分支

bool isinstack[7]; //是否在棧中

bool visited[7]; //是否訪問過

void init();

int j[8]=;

for(int m=1;m<=6;m++) //初始化鄰接矩陣

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

g[m][n]=0;

for(int k=0;k<8;k++) //增加邊

g[i[k]][j[k]]=1;

for(int k=1;k<=6;k++)

}void tarjan(int i)

回退到上乙個頂點5

low(5)=min( low(5) ,low(6))= 3

dfn == low ,出棧得到連通分支

回退到上乙個頂點3

low(3)=min( low(3) ,low(5))= 2

有邊3->4(狀態1),tarjan(4):

有邊4->6(狀態3)

有邊4->1(狀態2):

low(4)=min( low(4) ,dfn(1))= 1

dfn != low

回退到上乙個頂點3

low(3)=min( low(3) ,low(4))= 1

dfn != low

回退到上乙個頂點1

low(1)=min( low(1) ,low(3))= 1

有邊1->2(狀態1),tarjan(2):

有邊2->4(狀態2):

low(2)=min( low(2) ,dfn(4))= 5

dfn != low

回退到上乙個頂點1

low(1)=min( low(1) ,low(2))= 1

dfn == low ,,出棧得到連通分支

上述過程迴圈

有向強連通分支Tarjan演算法

本文 自 說到以tarjan命名的演算法,我們經常提到的有3個,其中就包括本文所介紹的求強連通分量的tarjan演算法。而提出此演算法的普林斯頓大學的robert e tarjan教授也是1986年的圖靈獎獲得者 具體原因請看本博 歷屆圖靈獎得主 一文 首先明確幾個概念。強連通圖。在乙個強連通圖中,...

強連通分支

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

tarjan 演算法 求強連通分量)

全網最詳細tarjan演算法講解,我不敢說別的。反正其他tarjan演算法講解,我看了半天才看懂。我寫的這個,讀完一遍,發現原來tarjan這麼簡單!tarjan演算法,乙個關於 圖的聯通性的神奇演算法。基於dfs 迪法師 演算法,深度優先搜尋一張有向圖。注意!是有向圖。根據樹,堆疊,打標記等種種神...