//poj2186 強聯通圖模板 節點數1w 邊數5w 79ms g++
#includeconst int sz = 50000+10;
struct edge
;edge edge[sz]; //存放邊
int head[sz]=;//每個節點的第一條邊的編號
int n,m;//有n個節點,m條邊
int cnt;//邊的編號
int stack[sz];//棧
int top;
int dfn[sz]=,low[sz]=;//targin要用的變數
bool instack[sz]=;//是否存在棧中
int c = 0;//遞增量 ,時間戳
int sc = 0 ;//一共有多少個聯通分量
int count[sz]=;//每個聯通分量有多少個節點
int min(int a,int b)
id = i;
} }printf("%d\n",count[id]);
}void init()
}int main()
for(int i=1;i<=n;i++)//不聯通 }
solve();
return 0;
}
強聯通圖縮點後:得到乙個dag(有向無環圖),得到這個dag我們可以處理一些問題:
1.問:是否存在某些點(point1或point2 。。。。。),使得 所有的點是否可以匯聚到這個點(point1 或 point2 。。。。。)上,比如3個點1 2 3 ,1-->2 2-->1 2-->3 畫圖可知 1 2 都可以匯聚到3上面,
問題可以轉化為 一共有多少個出度為0 的強連通圖 ,如果只有1個,則結果就是該連通圖的節點數,如果》1 ,則沒有。因為最終的dag,如果有2個強聯通圖沒有出度,
則必定有乙個點 得不到另外乙個點的匯聚。
2.問:有乙個訊息,如果a 到b右一條有向邊a-->b,則a可以把訊息傳給b,問我們至少需要選擇多少個點,作為資訊的源點,最終可以使得每乙個節點都獲得該 訊息
3.問: 我們至少需要新增多少條有向邊,才可以使得整個圖為強聯通圖
問題轉化為: 計算得到 入度為0的強聯通圖個數 in0 , 計算得到出度為0的強聯通圖的個數 out0,然後結果就是max(in0,out0)。因為強聯通圖必然是每個點都有出度和入度,
所以我們必須為沒有入度或者出度的點 連邊,那麼最少就需要max(in0,out0)條邊。
targin 強聯通分量 縮點
在乙個有向圖g中,如果兩個頂點間至少存在一條路徑,稱兩個頂點強聯通。如果所有頂點都強聯通,稱g是乙個強聯通圖。非強聯通圖有向圖的極大強聯通子圖,稱為強聯通分量。深度優先搜尋。dfn i 節點i被搜尋到的次序編號。low i i或i的子樹能夠追溯到的最早的節點的次序號。low i min dfn i ...
強聯通分量
有向圖中 u可達 v不一定意味著v可達 u.相互可達則屬於同乙個強連通分量 strongly connected component,scc 最關鍵通用部分 強連通分量一定是圖的深搜樹的乙個子樹。1.演算法思路 基本思路 這個演算法可以說是最容易理解,最通用的演算法,其比較關鍵的部分是同時應用了原圖...
強聯通分量
include include include include include include include include using namespace std struct edge vectora 80005 b 80005 node 80005 int he 80005 int n,m,...