今天比較無聊開始複習圖論,對於我這麼乙個不怎麼愛寫板子的蒟蒻來說,終於打算回(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 演算法是基於對圖優先搜素的演算法 每...