[複習] 圖連通性

dengchengyu發表於2024-10-25

[複習] 圖連通性

搜尋生成樹

定義(無向邊方向是邊第一次被遍歷時所指的方向)

  • 樹邊,搜尋到一個新的點連的邊,構成生成樹。
  • 返祖邊,搜尋到一個指向當前點到根的路徑上的一個點的邊。
  • 前向邊,指向生成樹子樹內一個點的邊。
  • 橫叉邊,其他邊,指向兄弟子樹。

有向圖dfs生成樹 以上四種邊都有。

無向圖dfs生成樹 只有樹邊和返祖邊。

無向圖bfs生成樹 只有樹邊和橫叉邊。

Tarjan 演算法

SCC 強連通分量

在有向圖中,兩個點強連通當且僅當兩點互相可達。

強連通分量是極大的滿足每個點兩兩強聯通的子圖。

注意到在 \(dfs\) 樹上,一個環只有可能由樹邊和返祖邊構成。

定義 \(dfn\) 表示 \(dfs\) 序,\(low\) 表示經過樹邊和返祖邊能到達的最小的 \(dfn\)

如果一個點的 \(dfn=low\) 那麼它就是這個 SCC 中深度最小的點。

我們到達一個新的點,將它加入棧,之後只用棧中的 \(dfn\) 更新 \(low\)

同時當我們找到一個 \(dfn_x=low_x\) 時,此時棧中在 \(x\) 以上的點都和 \(x\) 在用一個 SCC 中。

vector<int> g[N];
int dfn[N],low[N],dfn1;
int stk[N],bz[N],top; // bz:是否在棧中
int scc[N],sc; // 所在 SCC 的標號
void dfs(int x){
	dfn[x]=low[x]=++dfn1,stk[++top]=x,bz[x]=1;
    for(int v:g[x]) 
        if(!dfn[v])dfs(v),low[x]=min(low[x],low[v]);
    	else if(bz[v])low[x]=min(low[x],dfn[v]);
    if(dfn[x]==low[x]){
        ++sc;
        while(bz[x])scc[stk[top]]=sc,bz[stk[top--]]=0;
    }
}

SCC 標號與拓撲序

SCC 的標號是 SCC 縮點後形成的 DAG 的拓撲序的逆序。

邊雙連通分量

無向圖。

分量內,刪除任意一條邊後,任意兩個點可達。

連線分量的邊叫做橋,或割邊。

點的邊雙連通性具有傳遞性。

在無向圖中,\(dfn\) 表示 \(dfs\) 序,\(low\) 表示不經過父邊能到達的最小 \(dfn\)

因此我們需要在 \(dfs\) 中記錄父親的

如果樹邊 \((x,v)\) 滿足 \(low_v>dfn_x\) 則這條邊是橋。

點雙連通分量

刪掉一個點後,分量內任意點兩點可達。

一個點可能屬於多個點雙,此時這個點是割點。

點的點雙連通性不具有傳遞性,因為一個點可能屬於多個點雙。

但一條邊一定只屬於一個點雙。

如果樹邊 \((x,v)\) 滿足 \(low_v\ge dfn_x\) 那麼 \(x\) 是割點,並且對於同一個 \(x\) 有不同的 \(v\) 滿足這個條件,那麼每個 \(v\) 都屬於不同的點雙。

相關文章