演算法學習之路 強連通分量 縮點

2021-09-21 15:21:51 字數 1491 閱讀 2864

本來寒假是安排的很充實的,放假了一回到家就(ノへ ̄、)

演算法想想還是不能丟,雖然離acm銅牌的水平還差好遠,但是,不想留下遺憾,演算法慢慢的要重新拾起來的,雖然以前水平也不咋地╯︿╰

題目大意:一張有向圖,問至少再新增幾條有向邊,才能使它成為強連通圖。

主要寫一下本題大致用到了哪些方面的知識,理一下思路。

強連通分量:在有向圖中,如果一張圖中的任意兩點都可以相互到達,則稱這個圖為強連通圖。圖中任意兩點之間可以相互到達的子圖即為強連通分量。

tarjan演算法:本質是通過一次dfs搜尋有向圖,用棧儲存到達過的節點,每求出乙個完整的強連通分量,就彈出對應的節點,計算強連通分量的個數(即之後縮點後點的個數)。

tarjan演算法的詳解可以看這位博主的部落格:

縮點:在每次求得乙個強連通分量時,給當前強連通分量中的節點打上同乙個標記,看成同乙個節點,即縮點。

入度、出度:如有向邊(u,v)不在同乙個強連通分量中,則u所在強連通分量出度++,v所在強連通分量入度++。

計算入度為0和出度為0的強連通分量個數n,m

構成強連通圖需要新增的最少邊就是max(n,m),因為出度為0的點無法到達其他節點,入度為0的點無法被到達,則至少使得所有點入度和出度都大於0才能構成強連通圖。

tarjan演算法**

注意!這不是ac**!(由於用的鄰接矩陣儲存邊,最後記憶體超了)

#include#include#include#define maxn 10005

using namespace std;

int raid[maxn][maxn];

int low[maxn],dfn[maxn],sta[maxn],flag[maxn],suo[maxn],indegree[maxn],outdegree[maxn];

int idex=1,number=0,top=0,n,m;//idex時間戳,number強連通分量個數,top sta棧中位置

void tarjan(int u)

else//被訪問過}}

}//往後回溯,將棧中屬於同一強連通分量的節點全部彈出

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

number++;

dowhile(i!=u);

}int main()

int in=0,out=0,max=0;//入度和出度

tarjan(1);//若初始圖不一定連通則需要迴圈呼叫tarjan函式

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

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

max=max(in,out);

printf("%d\n",max);

}return 0;

}

演算法 強連通分量縮點

有時對於乙個有向圖我們及其渴望將其變為乙個有向無環圖,這樣我們就要用到強連通分量縮點了。洛谷3387 縮點 題目背景 縮點 dp。題目描述 給定乙個 n個點 m條邊有向圖,每個點有乙個權值,求一條路徑,使路徑經過的點權值之和最大。你只需要求出這個權值和。允許多次經過一條邊或者乙個點,但是,重複經過的...

強連通分量(縮點)學習筆記 (updating)

由於本人的文化課炸掉了,所以說從此用心開始學計算機,再也不插科打諢了。在乙個有向聯通圖中,如果說有若干個點之間成乙個環 即任意兩點之間可以互相到達 那麼我們稱這些點為乙個強連通分量,下文統一用 scc 來表示。在對圖論問題的分析中,其可以進行縮點,割邊等優秀操作來節省操作難度。luogu p3387...

強連通分量縮點的模板

include include include include using namespace std define inti a memset a,0,sizeof a define min a,b a b b a define max a,b a b a b const int max 1605...