對於Tarjan強連通分量演算法的理解

2021-07-27 07:49:25 字數 2423 閱讀 2989

今天比較無聊開始複習圖論,對於我這麼乙個不怎麼愛寫板子的蒟蒻來說,終於打算回(yu)顧(xi)一下tarjan的強連通演算法

首先給出tarjan演算法的原理:

tarjan的演算法主要基於dfs樹,基本和求點雙,邊雙什麼的差不多。對於一棵dfs樹,我們肯定是按照dfs序來遍歷它的(因為它叫dfs樹)。這時,我們記錄乙個叫做lowlink的陣列,對於lowlonk[x]來說,它記錄的是在這棵dfs樹上編號為x的節點所能夠達到的最早的節點

然後,我們每次用x的後繼節點以及dfs樹上的反向邊所指向的節點(反向邊,即非樹邊,原圖中存在但由於dfs序的原因未出現於dfs樹上的邊)的lowlink來更新x的lowlink,在這裡我們應該使用min()函式,因為lowlink越小表示訪問的時間越早。

最後,我們只要考慮這樣的節點x,它滿足pre[x]==lowlink[x],這說明它最早到達的節點是它自己,那麼它與它的後繼們就在同乙個強連通分量中(其實這裡表示並不嚴密,是指x節點的特定的後繼,如果它的某些後繼已經被確定屬於某個強連通分量了,那麼這個後繼就不算)。這樣我們就求出了所有的強連通分量。演算法中還有很多的細節,下文將予以說明

先貼上本人醜陋的**(**中low==lowlink):

vector

geo[maxn];

stack

scc;

bool vis[maxn];

int sccno[maxn],low[maxn],pre[maxn];

int time=0,cnt=0;

int tarjan(int x)else

if(!sccno[op])

}if(low[x]==pre[x])

sccno[x]=cnt;

}return low[x];

}

忍不住吐個槽,markdown的有序列表功能真是爛到不行

**不長,理解起來並不困難,雖然也不是經常使用(相對於dp,數學什麼的來說),但是會了總比不會強

由於外國間諜的大量滲入,****正處於高度的危機之中。如果a間諜手中掌握著關於b間諜的犯罪證據,則稱a可以揭發b。有些間諜收**賂,只要給他們一定數量的美元,他們就願意交出手中掌握的全部情報。所以,如果我們能夠收買一些間諜的話,我們就可能控制間諜網中的每一分子。因為一旦我們逮捕了乙個間諜,他手中掌握的情報都將歸我們所有,這樣就有可能逮捕新的間諜,掌握新的情報。

我們的反間諜機關提供了乙份資料,色括所有已知的**的間諜,以及他們願意收受的具體數額。同時我們還知道哪些間諜手中具體掌握了哪些間諜的資料。假設總共有n個間諜(n不超過3000),每個間諜分別用1到3000的整數來標識。

請根據這份資料,判斷我們是否有可能控制全部的間諜,如果可以,求出我們所需要支付的最少資金。否則,輸出不能被控制的乙個間諜。

輸入格式:

第一行只有乙個整數n。

第二行是整數p。表示願意被收買的人數,1≤p≤n。

接下來的p行,每行有兩個整數,第乙個數是乙個願意被收買的間諜的編號,第二個數表示他將會被收買的數額。這個數額不超過20000。

緊跟著一行只有乙個整數r,1≤r≤8000。然後r行,每行兩個正整數,表示數對(a, b),a間諜掌握b間諜的證據。

輸出格式:

如果可以控制所有間諜,第一行輸出yes,並在第二行輸出所需要支付的賄金最小值。否則輸出no,並在第二行輸出不能控制的間諜中,編號最小的間諜編號。

輸入樣例

【樣例1】

3 2

1 10

2 100

2 1 3

2 3

【樣例2】

4 2

1 100

4 200

2 1 2

3 4輸出樣例:

【樣例1】

yes

110

【樣例2】

no 3

這是一道洛谷的題。。。

每頭奶牛都夢想成為牛棚裡的明星。被所有奶牛喜歡的奶牛就是一頭明星奶牛。所有奶

歡b,b喜歡c,那麼a也喜歡c。牛欄裡共有n 頭奶牛,給定一些奶牛之間的愛慕關係,請你

算出有多少頭奶牛可以當明星。

第一行:兩個用空格分開的整數:n和m

第二行到第m + 1行:每行兩個用空格分開的整數:a和b,表示a喜歡b

第一行:單獨乙個整數,表示明星奶牛的數量

輸入樣例#1:

3 3

1 2

2 1

2 3輸出樣例#1:只有 3 號奶牛可以做明星

10%的資料n<=20, m<=50

30%的資料n<=1000,m<=20000

70%的資料n<=5000,m<=50000

100%的資料n<=10000,m<=50000

這是一道洛谷上的題。。。

強連通分量Tarjan演算法

o v e 通常的tarjan寫法是有個dfn陣列跟乙個instack陣列,我精簡了下 把這兩個陣列都刪去了,用更簡便的寫法代替,也省了空間。int low maxn 記錄這棵樹能到達的最早祖先 其實不一定是最早,但不影響使用 int time 時間戳 int num 連通分量的個數 int bel...

強連通分量 tarjan演算法

強連通分量 tarjan演算法 有向圖強連通分量 在有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強連通 strongly connected 如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。非強連通圖有向圖的極大強連通子圖,稱為強連通分量 strongly connected com...

強連通分量 Tarjan演算法

有向圖強連通分量 在有向圖g中,如果兩個頂點vi,vj間 vi vj 有一條從vi到vj的有向路徑,同時還有一條從vj到vi的有向路徑,則稱兩個頂點強連通。如果有向圖g的每兩個頂點都強連通,稱g是乙個強連通圖。有向圖的極大強連通子圖,稱為強連通分量。tarjan 演算法是基於對圖優先搜素的演算法 每...