演算法筆記 割點與割邊

2022-08-03 03:15:12 字數 2089 閱讀 2595

一般用 tarjan 演算法解決

橋和割邊是乙個東西

若對於無向連通圖的乙個點 \(x\),從圖中刪去這個點和與這個點相連的所有邊後,圖不再是連通圖,則 \(x\) 為這個圖的割點。

若對於無向連通圖的一條邊 \(e\),從圖中刪去這條邊後,圖不再是連通圖,則 \(e\) 為這個圖的割邊。

當然那張圖可能本來就不連通,所以嚴格來說是把乙個連通塊斷開了,改變了原來的連通塊是否連通,是這個連通塊的割點或割邊。不過從總體來看,刪除這個點或邊還是改變了整張圖的連通性。

與有向圖 dfs 樹類似。

任選乙個點開始出發進行 dfs,保證每乙個點只訪問一次,把所有發生了遞迴的邊標為樹邊,所有樹邊構成一棵樹。

對應到樹上,每乙個點都只有乙個父親節點,就是第一次訪問這個點時對應的那個點(第二次訪問時就直接跳過這個點了)。

還是來張圖(紅色為樹邊):

然後將邊分為兩類,樹邊和返祖邊,返祖邊連線了乙個點和它的乙個祖先。

注意,與有向圖不同,無向圖 dfs 樹沒有橫叉邊。

在 dfs 的過程中,按每乙個節點第一次被訪問的順序,給每個點標上乙個數字,代表是第幾個被第一次訪問的,記為時間戳。

\(u\) 的追溯值指的是 \(u\) 的子樹中所有點 和 從 \(u\) 的子樹中的點通過僅一條返祖邊可以到達的點的時間戳的最小值

下圖中,黑色數字代表每個點的 dfn,紅色數字代表 low。

首先注意到,割邊只可能是樹邊,不可能是返祖邊

假設 \(u\) 是 \(v\) 的父親,如果從 \(v\) 的子樹中任意一點出發都不能到達 \(u\) 或 \(u\) 的祖先,也就是時間戳比 \(x\) 小的點(不要管那些點的其它子樹,由於沒有橫叉邊,它們只能通過先走到 \(u\) 或 \(u\) 的祖先再往下走到達),那麼刪去這條邊後,\(v\) 的子樹就與圖的其它部分斷開了。

判斷條件就是 \(low_v>dfn_u\)

否則的話,\(v\) 就有至少兩條路到達 \(u\),一條是 \((v,u)\) 另一條是先向下走到子樹中某個點,再走返祖邊,再向下走到 \(u\)。

void tarjan(ll u,ll fe)

else if(i != (fe ^ 1)) low[u] = min(low[u],dfn[v]);

// 這條邊是返祖邊,所以取 dfn,這裡一定不能取 low

// 存邊的時候,把 (u,v) 和 (v,u) 分別存為 2,3/4,5/6,7/... 通過 ^1 就是另一條邊的編號

// 算 low 的時候不能把父親節點的 dfn 算進去

// 同時,這樣可以處理重邊的情況

}}

思想類似。

若 \(u\) 是割點,那麼只要存在\(u\) 的乙個子節點 \(v\),使得 \(low_v \geq dfn_u\),則 \(u\) 是割點。

相應的,刪去 \(u\) 後 \(v\) 無法到達 \(u\) 或 \(u\) 的祖先了

還有乙個特殊情況,就是對於搜尋樹的根,如果它只有 1 個兒子(通過樹邊與之直接相連的點),它不能成為割點,這裡需要特判。

樹的葉子節點由於沒有兒子,也不會成為割點。

inline void tarjan(ll u,ll fa)

else low[u] = min(low[u],dfn[v]);

// 這裡判定的時候取的是小於等於,所以可以無視父邊影響

// 重邊也是沒有影響的,因為我刪除的是點}}

應用之一:雙連通分量

tarjan演算法求割點割邊

在上一節我們已經知道tarjan演算法可以求聯通圖,在這裡我們也運用tarjan的思想求割點與割邊,首先我們先來說說割點,那麼什麼事割點呢,先來看一張圖 a 來自網路 在 a 圖中,我們將a點以及與a點相連的邊全部去除,會發現這個聯通圖被分成了倆個聯通圖,乙個是節點f,另外乙個是餘下的所有的節點組成...

割點 割邊 tarjan

洛谷割點模板題 傳送門 割邊 在連通圖中,刪除了連通圖的某條邊後,圖不再連通。這樣的邊被稱為割邊,也叫做橋。割點 在連通圖中,刪除了連通圖的某個點以及與這個點相連的邊後,圖不再連通。這樣的點被稱為割點。dfs搜尋樹 用dfs對圖進行遍歷時,按照遍歷次序的不同,我們可以得到一棵dfs搜尋樹。樹邊 在搜...

割點和割邊

在無向圖中,所有能互通的點組成了乙個 連通分量 在乙個連通分量中有一些關鍵的點,如果刪除它們,會把這個連通分量分成兩個或更多,這種點稱為割點 cut vertex 類似的有割邊 cut edge,又稱為橋,bridge 問題。在乙個連通分量中,如果刪除一條邊,把這個連通兩個 注意邊最多只能分成兩個 ...