藍書的那一套理論比較生硬,且不是很深刻,故重學Tarjan。AlexWei《圖論Ⅰ》
相關定義
割點:在無向圖中,刪去使得連通分量數增加的點被稱為割點。
割邊:在無向圖中,刪去使得連通分量數增加的邊被稱為割邊。
點雙連通圖:不存在割點的無向圖。
邊雙連通圖:不存在割邊的無向圖。
點雙連通分量:一張圖的極大點雙連通子圖稱為點雙連通分量(V-BCC),簡稱點雙。
邊雙連通分量:一張圖的極大邊雙連通子圖稱為邊雙連通分量(E-BCC),簡稱邊雙。
縮點:把一個連通分量等價為一個點的操作。邊雙和點雙縮點後均得到一棵樹,而強連通分量縮點後得到一張DAG。
基本性質
邊雙連通
考慮割邊兩側的兩個點 \(u,v\)。由於刪去割邊 \(u,v\) 不連通,所以這條割邊在任何一條 \(u\) 到 \(v\) 的跡上,否則刪去後 \(u,v\) 仍連通。
兩點之間的所有必經邊,就是連線它們所有跡的交。
在研究必經邊時,重複經過一條邊是不優的,所以只需考慮兩點之間的跡(路徑邊集不重複)。
不難發現,割邊和必經邊的概念是完全等價的。\(u, v\) 雙連通當且僅當 \(u, v\) 之間不存在必經邊。
斷開一條割邊會使連通塊數 +1。斷開所有割邊,每個連通塊中不含割邊且不能再擴大,是原圖的邊雙連通分量。
這說明邊雙連通分量由割邊連線,邊雙縮點得到一顆樹,每條邊都是原圖割邊。
任意新增一條邊 \((u, v)\),任意 \(u, v\) 簡單路徑上的邊不再是割邊了,即該路徑上的所有邊雙會被縮成一個大邊雙。
傳遞性:若 \(u, v\) 雙連通,\(v, w\) 雙連通,則 \(u, w\) 雙連通。
證明:\(u, v\) 之間跡的交集為空(沒有必經邊),空集與空集取交還為空,因此 \(u, w\) 之間沒有必經邊。
結論:邊雙的點集兩兩無交,每個點恰屬於一個邊雙,根據傳遞性易證。
結論:對於邊雙內任意一條邊 \((u,v)\),存在經過 \((u,v)\) 的迴路;對於任意一點 \(u\),存在經過 \(u\) 的迴路(除孤立點)。
證明:考慮邊 \((u, v)\),將其刪去後仍能得到一條 \(u, v\) 的路徑,將該路徑與 \((u, v)\) 拼起來,即可得到穿過 \(u, v\) 的迴路。
點雙連通
與邊雙不同,兩個點雙可能有交,例如 "8字形",中間的交點在兩個點雙都出現了。
因此點雙不具有傳遞性。但如果兩個點雙有交,交點一定唯一,否則兩個點雙可以合併。
結論:若兩點雙有交,那麼交點一定是割點。如果刪去交點後兩點雙仍然連通,則可以合併。
引理:若兩點點雙連通,那麼包含這兩點的點雙唯一。不唯一則出現兩個交點,矛盾。
現在已經知道點雙交點是割點,那麼割點一定是點雙交點嗎?刪去割點,考慮割點的兩個鄰居 \(u, v\)。
根據定義,\(u, v\) 不連通,則 \(u, v\) 不屬於一個點雙。
結論:一個點是割點當且僅當屬於超過一個點雙(上面充分性和必要性都有證明)。
結論:由一條邊直接相連的兩點點雙連通。
推論:一條邊恰屬於一個點雙。\((u, v)\) 連線的 \(u, v\) 屬於一個點雙,如果他們同時屬於另一個點雙則產生矛盾。
正如割邊是連線邊雙的「橋樑」,割點也是連線點雙的橋樑。
用一個點代表一個點雙,並將這個代表點向與之相連的割點連邊,得到塊割樹。
考慮刪去點雙中的一個點 \(x\),剩下所有點連通。
如果度數大於 \(1\),對於其不同的兩個鄰居 \(u, v\),將新圖中 \(u, v\) 的路徑與 \(x\) 相連,得到經過 \(x\) 的簡單環。
若度數等於 \(1\),則整個點雙為"一邊連兩點"的平凡形態,即只可能在 \(n = 2\) 的時候出現。
如果 \(n \ge 3\) 且存在 \(d(u) = 1\),設與其直接相連的唯一點為 \(v\),刪去 \(v\) 後 \(u\) 與整張圖不連通,矛盾。
結論:對於 \(n \ge 3\) 的點雙中任意一點 \(u\),存在經過 \(u\) 的簡單環。
Tarjan求割點
無向圖DFS樹
給定無向連通圖 \(G\),從 \(r\) 開始 dfs。取出進入每個點時的邊 \((fa_i,i)\) 稱為樹邊,其它為非樹邊,得到以 \(r\) 為根的樹。
無向圖 DFS 樹的性質:
- 祖先後代性:任意非樹邊兩端具有祖先後代關係。
- 子樹獨立性:節點的每個兒子的子樹之間沒有邊(和上一條性質等價)。
- 時間戳區間性:子樹時間戳為一段連續區間。
- 時間戳單調性:節點的時間戳小於其子樹內的時間戳。
後兩點比較顯然,證一下前兩點,對於 \(u\) 所有的出邊 \(v\):
\(v\) 還沒遍歷到,未來一定在 \(u\) 的子樹中(不一定是兒子);\(v\) 已經被遍歷到,\(u\) 對於 \(v\) 來說是沒被遍歷,\(u\) 在 \(v\) 的子樹中。
非根節點的割點判定
記 \(x\) 的子樹 \(T(x)\) 為 \(x\) 在 DFS 樹上的子樹,記 \(T(x)^\prime = V\setminus T(x)\),即整張圖除 \(T(x)\) 以外的部分。
設 \(x\) 不為根,則 \(T^\prime(x) \ne \emptyset\),
刪掉 \(x\) 之後 \(T(x)^\prime\) 透過樹邊相連仍然連通,若 \(x\) 是割點則存在 \(z \in T^\prime(x)\) 與 \(y\) 不連通,顯然 \(y \in T(x)\)。
由於 \(y, z\) 不連通,\(T^\prime(x)\) 連通,則 \(y\) 與整個 \(T^\prime(x)\) 不連通。反之如果存在 \(y\) 與 \(T^\prime(x)\) 不連通,\(x\) 一定是割點。
條件等價於任意 \(y \in T(x)\) 不經過 \(x\) 能到達點均屬於 \(T(x)\)。
如果 \(y \in T(x)\) 不經過 \(x\) 就與 \(T^\prime(x)\) 連通,一定存在 \(y\) 到 $v \in T^\prime(x) $ 的路徑,使得 \(v\) 是路徑中第一個屬於 \(T^\prime(x)\) 的點。
設 \(u\) 為路徑中倒數第二個點,有 \(u \in T(x)\)。如果 \((u, v)\) 是樹邊,則 \(u = x\),矛盾。
所以 \((u, v)\) 是非樹邊,\(v\) 是 \(u\) 的祖先,同理 \(v\) 也是 \(x\) 的祖先,一定有 \(d_v < d_u\)。
進一步的,由於 \(x\) 的不同兒子之間沒有非樹邊(子樹獨立性),設 \(x\) 的兒子 \(y^\prime\) 是 \(y\) 的祖先,則 \(u \in T(y^\prime)\)。
因此,如果 \(y\) 能夠不經過 \(x\) 和 \(T^\prime(x)\) 連通,則存在 \(u \in T(y^\prime)\) 滿足 \(u\) 有一條非樹邊與 \(x\) 的祖先直接相連。
設 \(f_x\) 表示 \(x\) 透過非樹邊能(直接)到達的最小時間戳。
\(x\) 不是割點的條件可以寫成:對於任意兒子 \(y^\prime\),都存在 \(u \in T(y^\prime)\),使得 \(f_u < d_x\)。
如果存在 \(f_u < d_x\),\(u\) 直接與 \(T^\prime(x)\) 相連,\(y^\prime\) 的其他點先透過樹邊先 \(u\) 相連,再間接與 \(T^\prime(x)\) 連通;
否則刪掉 \(x\) 後任意 \(y^\prime\) 子樹內的點都不與 \(T^\prime\) 連通,\(x\) 是割點。
得到非根節點的割點判定法則:如果存在兒子 \(y^\prime\),使得 \(\min_{ u \in T(y^\prime)}f_u \ge d_x\),則 \(x\) 是割點。
設 \(g_x\) 表示 \(x\) 子樹內 \(f_u\) 的最小值(low
陣列的真正含義):
當且僅當存在 \(x\) 的兒子 \(y\) 滿足 \(g_{y} \ge d_x\),\(x\) 是割點。
根據上述 DP 的定義,\(g_x\) 顯然是初始化成 \(\inf\)。當然初始化成 \(d_x\) 也不會有錯,程式碼上只是多一行少一行的區別。
(感覺聽魏老師講完,整個人都清澈了!)
根的割點判定法則
若 \(x\) 在 DFS 樹上有 \(> 1\) 個兒子,根據子樹獨立性,\(x\) 的兒子兩兩不連通,\(x\) 是割點。
如果 \(x\) 只有一個兒子 \(y\),刪掉 \(x\) 後 \(T(y)\) 仍然連通,\(x\) 不是割點。
割邊求法
Tarjan
探究 \(e = (u, v)\) 是割邊的充要條件。
樹邊使整張圖連通,割斷非樹邊不影響連通性,因此 \(e\) 是割邊的一個必要條件是 \(e\) 是樹邊。
不妨設 \(v\) 是 \(u\) 的兒子,如果割點 \(e\) 後圖不連通,只能分成 \(T(v)\) 和 \(T^\prime(v)\) 兩部分,因為其內部都透過樹邊連通。
這說明 \(T(v)\) 的所有節點都必須經過 \(e\) 才能到達 \(T^\prime(v)\)。
如果存在 \(w \in T(v)\),\(w\) 能過透過一條非樹邊到達 \(u\) 或其祖先,則 \(e\) 不是割邊,即 \(\min_{w \in T(v)} f_w = g_v \le d_u\)。
割邊判定法則:對於樹邊 \(e = (u, v)\),\(v\) 是 \(u\) 的兒子,\(e\) 是割邊當且僅當 \(g_v > d_u\)。
樹上差分
已經知道樹邊是割邊的一個必要條件。
如果存在非樹邊 \((u, v)\),那麼搜尋樹上 \(u \to v\) 的簡單路徑上所有樹邊都不是割邊了。
怎麼刻畫一條樹邊有沒有被非樹邊覆蓋?把邊 \((i, fa_i)\) 的覆蓋次數當做 \(i\) 的點權,樹上差分後求子樹和。
邊雙連通分量縮點
由於每個點恰屬於一個邊雙,把每個割邊割斷後剩下的每個連通塊都是一個邊雙。
可以先 Tarjan 給所有割邊打上標記,再 dfs 找連通分量,但太麻煩。