強連通分量(超詳細!!!)

強連通分量(超詳細!!!)

一、定義

在有向圖G中,如果兩個頂點u,v間有一條從u到v的有向路徑,同時還有一條從v到u的有向路徑,則稱兩個頂點強連通。如果有向圖G的每兩個頂點都強連通,稱G是一個強連通圖。有向非強連通圖的極大強連通子圖,稱爲強連通分量。

圖中,子圖{1,2,3,4}爲一個強連通分量,因爲頂點1,2,3,4兩兩可達。{5},{6}也分別是兩個強連通分量。

二、tarjan算法 時間複雜度是O(N+M)

四條邊:

樹枝邊:DFS時經過的邊,即DFS搜索樹上的邊。

前向邊:與DFS方向一致,從某個結點指向其某個子孫的邊。

後向邊:與DFS方向相反,從某個結點指向其某個祖先的邊。(返祖邊)

橫叉邊:從某個結點指向搜索樹中的另一子樹中的某結點的邊。

 

Tarjan算法是基於對圖深度優先搜索的算法,每個強連通分量爲搜索樹中的一棵子樹。搜索時,把當前搜索樹中未處理的節點加入一個堆棧,回溯時可以判斷棧頂到棧中的節點是否爲一個強連通分量。 定義DFN(u)爲節點u搜索的次序編號(時間戳),Low(u)爲u或u的子樹能夠追溯到的最早的棧中節點的次序號。 由定義可以得出,Low(u)=Min {Low(u), Low(v) } (u,v)爲樹枝邊,u爲v的父節點 . Low(u)=Min {Low(u), DFN(v) } DFN(v),(u,v)爲指向棧中節點的後向邊(指向棧中結點的橫叉邊) } 當結點u搜索結束後,若DFN(u)=Low(u)時,則以u爲根的搜索子樹上所有還在棧中的節點是一個強連通分量。

算法過程:

從節點1開始DFS,把遍歷到的節點加入棧中。搜索到節點u=6時,DFN[6]=LOW[6],找到了一個強連通分量。退棧到u=v爲止,{6}爲一個強連通分量。

初始化時Low[u]=DFN[u]=++index

返回節點5,發現DFN[5]=LOW[5],退棧後{5}爲一個強連通分量。

 

返回節點3,繼續搜索到節點4,把4加入堆棧。發現節點4向節點1有後向邊,節點1還在棧中,所以LOW[4]=1。節點6已經出棧,(4,6)是橫叉邊,返回3,(3,4)爲樹枝邊,所以LOW[3]=LOW[4]=1。

Low(u)=Min {Low(u), DFN(v) } DFN(v),(u,v)爲指向棧中節點的後向邊

 

繼續回到節點1,最後訪問節點2。訪問邊(2,4),4還在棧中,所以LOW[2]=DFN[4]=5。返回1後,發現DFN[1]=LOW[1],把棧中節點全部取出,組成一個連通分量{1,3,4,2}。

至此,算法結束。求出了圖中全部的三個強連通分量{1,3,4,2},{5},{6}。

三、tarjan算法用途

1、有向圖的縮點

將同一個強連通分量中的點縮成同一個新結點,對於兩個新結點a,b之間有邊相連,當且僅當存在兩個點u屬於a,v屬於b。

 

 

2、求割點和橋

三、例題

「例 1」受歡迎的牛(信息學奧賽一本通 1513)

【題目描述】

原題來自:USACO 2003 Fall

每一頭牛的願望就是變成一頭最受歡迎的牛。現在有 N 頭牛,給你 M 對整數 (A,B),表示牛 A 認爲牛 B 受歡迎。這種關係是具有傳遞性的,如果 A 認爲 B 受歡迎,B 認爲 C 受歡迎,那麼牛 A 也認爲牛 C 受歡迎。你的任務是求出有多少頭牛被除自己之外的所有牛認爲是受歡迎的。

【輸入】

第一行兩個數 N,M;

接下來 M 行,每行兩個數 A,B,意思是 A 認爲 B 是受歡迎的(給出的信息有可能重複,即有可能出現多個 A,B)。

【輸出】

輸出被除自己之外的所有牛認爲是受歡迎的牛的數量。

【輸入樣例】

3 3
1 2
2 1
2 3

【輸出樣例】

1

【提示】

樣例說明

只有第三頭牛被除自己之外的所有牛認爲是受歡迎的。

數據範圍:

對於全部數據,1≤N≤104,1≤M≤5×1041≤N≤104,1≤M≤5×104。


 

 

 

https://www.cnblogs.com/ljy-endl/p/11562352.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章