tarjan演算法詳解

2022-09-14 09:06:06 字數 1440 閱讀 5695

(4).對於乙個連通圖,我們很容易想到,在該連通圖中有且僅有乙個節點u的dfn值和low值相等。該節點一定是在深度遍歷的過程中,該連通圖中第乙個被訪問過的節點,因為它的dfn值和low值最小,不會被該連通圖中的其他節點所影響。

下面我們證明為什麼僅有乙個節點的dfn和low值相等。假設有兩個節點的dfn值和low值相等,由於這兩個節點的dfn值一定不相同 (dfn值的定義就是深度遍歷時被訪問的先後次序),所以兩個的low值也絕對不相等。由於位於同乙個連通圖中,所以兩個節點必定相互可達,那麼兩者的low值一定會被另外乙個所影響(要看誰的low值更小),所以不可能存在兩對dfn值和low值相等的節點。

所以我們在回溯的過程中就能夠通過判斷節點的low值和dfn值是否相等來判斷是否已經找到乙個子連通圖。由於該連通圖中的dfn值和low值相等的節點是該連通圖中第乙個被訪問到的節點,又根據棧的特性(先壓入  棧的節點在棧的更裡面),則該節點在最裡面。所以能夠通過不停的彈棧,直到彈出該dfn值和low值相同的節點來彈出該連通圖中所有的節點。

tarjan演算法的c++實現**如下,可以配合上面的圖加以理解:

[cpp]view plain

copy

#include

using namespace std;  

int dfn[105];                                  //記錄在做dfs時節點的搜尋次序  

int low[105];                                  //記錄節點能夠找到的最先訪問的祖先的記號  

int count=1;                                   //標記訪問次序,時間戳  

int stack[105];                                //壓入棧中  

int top=-1;  

int flag[105];                                 //標記節點是否已經在棧中  

int number=0;  

int j;  

int matrix[105][105]=,,,,,};  

int length;                                    //圖的長度  

void tarjan(int u)  

else                                  //flag在下面的do while中已經設為0了(即已經從棧中剔除了)  

}  }  

//往後回溯的時候,如果發現dfn和low相同的節點,就可以把這個節點之後的節點全部彈棧,構成連通圖  

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

cout<}  

}  int main()  

return 0;  

}  

tarjan演算法詳解

參考 tarjan演算法在強連通分量分離中運用很廣,書寫簡單,並且可以拓展到圖的割點,割邊上,十分強大 具體思路 令dfn u 表示當前點的時間戳 low u 表示當前點所能到達的點的時間戳中最小的乙個 到達點u時,將其入棧 拓展點u後代 當且僅當dfn u low u 時,棧頂元素全部出棧,此時出...

Tarjan演算法詳解

tarjan演算法的用途 1.求橋和割點 2.求點和邊的雙連通分量 3.求強連通 targan演算法的流程 利用dfs來遍歷圖來構建一種數型的結構 tarjan演算法的兩個核心陣列 1 對於第一種用途 tarjan演算法原理 我們從1開始遍歷,發現6,5,4的low不小於dfn 3 故3為割點 即4...

Tarjan演算法詳解

在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected components 所以我們在回溯的過程中就能夠通過判...