Tarjan求連通分量 縮點

2021-10-03 17:01:18 字數 1340 閱讀 2201

1.

強連通:在乙個圖中對於任意兩個點都可以互相到達那麼就稱這個圖為強連通圖。

連通分量:乙個圖的極大強連通子圖,稱為強連通分量

乙個連通分量比較類似於乙個集合,裡面的任點都可以互相到達

縮點:把乙個連通分量整體看作是乙個節點,那麼這個節點就是縮點

2.tarjan演算法:

考慮維護三個陣列:vis,dfn以及low

dfn: 表示該節點被遍歷到的時間戳(時間戳其實就是時間)

vis:該節點是否在棧中

low:該節點所能回溯到位於棧中節點的最小dfn值

具體過程可以看一道題來說:題目

可以看出就是按照是否可以相互到達把牛給分成多個集合實際上就是乙個裸的求連通分量的題:

#include

#define ll long long

#define inf 0x3f3f3f3f

using

namespace std;

const ll maxn =

1e5+5;

ll h[maxn]

,nex[maxn]

,e[maxn]

,cnt =1;

//鄰接表存圖

ll n,m,dfn[maxn]

,low[maxn]

,times,vis[maxn]

;///times用來計時

ll tot;

stack<

int> stk;

void

add(ll a,ll b)

void

tarjan

(int x)

else

if(vis[endd]

) low[x]

=min

(low[x]

,dfn[endd]);

//如果訪問到了乙個比自己小的在棧祖先那麼就更新自己}if

(low[x]

== dfn[x]

)//如果兩者相等那麼就開始出棧

if(cnt >1)

tot++

;//大於一的點才是所求}}

intmain()

for(

int i =

1; i <= n; i++)if

(!dfn[i]

)tarjan

(i);

//如果該點沒求那麼就從該點開始求連通分量

cout << tot << endl;

return0;

}

裸縮點題目:這裡

tarjan求強連通分量及縮點

一 概念 什麼是連通 強連通 弱連通?這裡有比較好理解的概念 二 方法 所涉及的內容皆圍繞cf999e 我們在計算強連通分量的時候會用到的工具 三 縮點 前面已經提到強連通分量的定義,即任意i點可以到達任意j點 那麼要是在強連通分量中再新增路徑就沒有必要 所以就可以把同屬於乙個強連通分量的節點看為同...

Tarjan求點雙連通分量

在乙個無向圖中,若任意兩點間至少存在兩條 點不重複 的路徑,則說這個圖是點雙連通的 簡稱雙連通,biconnected 在乙個無向圖中,點雙連通的極大子圖稱為點雙連通分量 簡稱雙連通分量,biconnected component,bcc 任意兩點間至少存在兩條點不重複的路徑等價於圖中刪去任意乙個點...

強連通分量 tarjan求強連通分量

雙dfs方法就是正dfs掃一遍,然後將邊反向dfs掃一遍。挑戰程式設計 上有說明。雙dfs 1 include 2 include 3 include 4 include 5 6using namespace std 7const int maxn 1e4 5 8 vector g maxn 圖的鄰...