tarjan 演算法 城堡迷宮

2021-09-11 05:43:49 字數 2681 閱讀 3273

一種求解有向圖強連通分量的線性時間的演算法。

也是乙個基於dfs深度優先搜尋的乙個有向圖

強連h通:如果兩個結點能夠相互到達,則稱這兩個結點強連通

強連線圖:如果有向圖g中任意兩個結點強連通,則稱這個有向圖g為強連線圖

強連通分量:對有向圖的乙個子圖,這個子圖任意兩個點滿足強連通,則稱這個子圖為有向圖g的強連通分量

栗子:

對於這個圖,1,2兩個點是強連通關係,因為1可以直接到2,2可以通過3到1;

對1,2,3,這三個結點是整個圖的乙個子圖,任意兩個點可以相互到達,是強連通分量;

1:dfn陣列:儲存的是當前結點是第幾個被搜尋的,作為這個點搜尋的時間戳,(每個點的時間戳都不一樣,且不能修改)

2:len陣列:儲存的是該子圖中,且仍在棧中的最小的時間戳(當所有點都更新完後,同一強連通分量中每個len[i]都相等,且是最小的)

//   可以用乙個陣列sta來實現堆疊

//scc陣列儲存每個強連通分量的編號

void tarjan(int u)

else if(!scc[t])                                 //scc陣列儲存的是該結點在第幾個強連通分量中

}if(dfn[u]==low[u])             //   如果u是這個強連通分量的根節點

}借鑑:

以1為tarjan 演算法的起始點,如圖

順次dfs搜到節點6

回溯時發現low[ 5 ]==dfn[ 5 ] ,  low[ 6 ]==dfn[ 6 ] ,則 , 為兩個強連通分量。回溯至3節點,拓展節點4.

拓展節點1 , 發現1再棧中更新low[ 4 ],low[ 3 ] 的值為1

回溯節點1,拓展節點2

自此,tarjan 演算法就結束了, ,  ,   為圖中的三個強連通分量。

不難發現,tarjan演算法的時間複雜度為o(e+v).

例題:a - 迷宮城堡    

為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間(n<=10000)和m條通道(m<=100000),每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩個房間都是相互連通的,即:對於任意的i和j,至少存在一條路徑可以從房間i到房間j,也存在一條路徑可以從房間j到房間i。

input

輸入包含多組資料,輸入的第一行有兩個數:n和m,接下來的m行每行有兩個數a和b,表示了一條通道可以從a房間來到b房間。檔案最後以兩個0結束。

output

對於輸入的每組資料,如果任意兩個房間都是相互連線的,輸出"yes",否則輸出"no"。

sample input

3 3

1 22 3

3 13 3

1 22 3

3 20 0

sample output

yes

no

完整**

#include#include#includetypedef long long ll;

const int xmax=1e6+100;

const int inf=1e9+7;

using namespace std;

int cnt,index;

int dfn[xmax];

int scc[xmax],sig;

int low[xmax];

int sta[xmax],top;

struct node

edge[xmax];

int head[xmax];

void init()

void addedge(int u,int v)

void tarjan(int u)

else if(!scc[t])

}if(dfn[u]==low[u])

}}int main()

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

if(sig!=1)

printf("no\n");

else

printf("yes\n");}}

迷宮城堡 tarjan演算法

為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間 n 10000 和m條通道 m 100000 每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩...

迷宮城堡 Tarjan

為了訓練小希的方向感,gardon建立了一座大城堡,裡面有n個房間 n 10000 和m條通道 m 100000 每個通道都是單向的,就是說若稱某通道連通了a房間和b房間,只說明可以通過這個通道由a房間到達b房間,但並不說明通過它可以由b房間到達a房間。gardon需要請你寫個程式確認一下是否任意兩...

tarjan演算法 杭電迷宮城堡。

思路 這題運用到tarjan演算法 剛看這個演算法一臉蒙b,然後通過閱讀別人的部落格算是掌握的差不多了。這個演算法中用到兩個陣列第乙個dfn,low,第乙個陣列是用來記錄深搜的順序的,第二個陣列是用來儲存i節點能夠追溯到他這個強連通分量最先深搜到的那個節點。具體的看演算法有關鍵注釋。我這裡簡單說下這...