(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 所以我們在回溯的過程中就能夠通過判...