图论复习——最小生成树MST
知識點
-
MST的構造
Boruvka算法常用于解決這類問題:給你n個點,每個點有點權,任意兩個點之間有邊權,邊權為兩個點權用過某種計算方式得出,求最小生成樹。動圖 -
MST上的確定性和存在性問題
-
最小生成樹的兩個性質:
(1) 不同的最小生成樹中,每種權值的邊出現(xiàn)的個數(shù)是確定的
(2) 不同的生成樹中,某一種權值的邊連接完成后,形成的聯(lián)通塊狀態(tài)是一樣的
可以用這兩個性質做最小生成樹計數(shù) -
Kruskal重構樹
-
令a,ba,ba,b路徑上最長邊最短: “最短的最長邊”一定在MST上,所以我們求一下MST,再在MST上找a,ba,ba,b路徑上的最長邊。
-
問nnn個點mmm條邊的無向連通圖上任兩點的最短距離,m?nm-nm?n很小:隨便建一棵生成樹,把圖看成樹上掛幾條邊 CF1051F The Shortest Statement
-
trick: 對區(qū)間[l,r][l,r][l,r]操作?\Rightarrow? 連邊l→r+1l\to r+1l→r+1
題
CF888G Xor-MST
Boruvka + 01Trie樹
Boruvka算法簡介:
對圖中所有的點iii,找到iii連向其它點的最小邊,如果這條邊還沒加進MSTMSTMST,就把它加上。執(zhí)行完后,把每個連通塊縮成點。
不斷重復上面的操作,直到只剩下一個連通塊。
時間復雜度O((m+n)logn)O((m+n)logn)O((m+n)logn)
此題中,要讓ai⊕aja_i \oplus a_jai?⊕aj?最小,就讓ai,aja_i,a_jai?,aj?的高位盡量保持相等。
假設我們現(xiàn)在運行Boruvka,并且目前只剩兩個連通塊,那么設ppp表示所有的aaa的第1~(p?1)(p-1)(p?1)位(從高位數(shù)起)都相等,在第ppp位才出現(xiàn)不同。
那么在這兩個連通塊中一定不會有 連接i,ji,ji,j且a[i]a[i]a[i]的第ppp位和a[j]a[j]a[j]的第ppp位不同的邊 ,也就是說aaa值的第ppp位為1的點構成一個連通塊,aaa值的第ppp位為0的點構成一個連通塊。
那么最后加入的邊一定是 連接i,ji,ji,j且a[i]a[i]a[i]的第ppp位和a[j]a[j]a[j]的第ppp位不同的邊,用 01Trie樹 找到這樣的最小邊。
加完最后一條邊,我們再遞歸回去,把aaa值的第ppp位為1的點連成一個連通塊,aaa值的第ppp位為0的點連成一個連通塊。
Code
CF1108F MST Unification
Blog
Code
CF733F Drivers Dissatisfaction
根據(jù)貪心,把SSS的費用全部用來降一條邊的權值不比用來降多條邊的權值劣。
枚舉每一條邊,看一下降這條邊的答案是多少,最后取最優(yōu)結果即可
先用Kruskal建出MST,設sumsumsum為MST里各邊的權值和。
-
如果降樹邊:
答案為sum??Sci?sum-\lfloor\frac{S}{c_i}\rfloorsum??ci?S??(保證降完后該邊是在MST里的) -
如果降非樹邊:
把降完權值后的非樹邊連上,原MST上出現(xiàn)一個環(huán),我們找到環(huán)上最大的邊刪掉即為新的MST。
每條非樹邊對應的環(huán)上最大邊邊權可以用倍增預處理出來。
Code
CF1416D Graph and Queries
Kruskal重構樹
不會刪邊。所以考慮離線,按時間倒序進行操作,刪邊變成加邊。
但是遇到的麻煩是,操作 1 是正序進行的,如果我們倒序操作,就不知道當前哪些點 pu=0p_u=0pu?=0 了。
解決方法是,先倒序遍歷一遍所有操作,按“加邊”的順序,建出重構樹。重構樹優(yōu)美的性質是,對任意一個節(jié)點 v,在某個時刻之前和它連通的節(jié)點,恰好在重構樹上 v 的某個祖先的子樹中。并且我們可以通過樹上倍增,在 O(logn)O(logn)O(logn) 的時間內找到這個祖先。
建出重構樹后,我們回到正向的時間線。按正序處理所有詢問(操作 1)。前面說過,在某個時刻和 v 連通的節(jié)點,在 v 某個祖先的子樹中。先倍增找到這個祖先。它的子樹是 dfs 序上連續(xù)的一段。我們預處理出重構樹的 dfs 序,那么問題轉化為求區(qū)間最大值,支持單點修改。可以用線段樹維護。
Code
CF1253F Cheap Robot
法一:
先預處理出disudis_udisu?表示uuu到最近的充電中心的距離(求多源最短路戳這)
從aaa到bbb的路徑 能經過邊(u→v,w)(u\to v,w)(u→v,w),當且僅當c?disu?w≥disvc-dis_u-w\geq dis_vc?disu??w≥disv?,即disu+disv+w≤cdis_u+dis_v+w\leq cdisu?+disv?+w≤c。
那么問題變成求一條從aaa到bbb的路徑使得路徑上每條邊的disu+disv+wdis_u+dis_v+wdisu?+disv?+w的最大值最小(明顯是滿足條件的最小的ccc)。
可以用Kruskal重構樹實現(xiàn),
也可以用NOIP2013貨車運輸/BZOJ3732 Network的套路實現(xiàn):
“最短的最長邊”一定在MST上,所以我們求一下MST,再在MST上找a,ba,ba,b路徑上的最長邊。
法二:
在任意兩個充電中心i,ji,ji,j之間連邊,邊權di,jd_{i,j}di,j?為原圖上i,ji,ji,j之間的最短距離。
那么ccc為新圖中從aaa到bbb的路徑上最長邊的最小值。法一中已經解決了這個問題。
現(xiàn)在的問題是如何求di,jd_{i,j}di,j?,這里介紹一種剪枝方法:
先跑多源最短路,對每個點iii求出離iii最近的充電中心fif_ifi?和到fif_ifi?的最短距離disidis_idisi?,然后枚舉原圖中的每條邊(u→v,w)(u\to v,w)(u→v,w),在新圖上連邊fu→fvf_u\to f_vfu?→fv?,邊權w′w'w′為disu+disv+wdis_u+dis_v+wdisu?+disv?+w,
可以證明minfu→fv{w′[fu→fv]}=du,vmin_{fu\to fv}\{w'[fu\to fv]\}=d_{u,v}minfu→fv?{w′[fu→fv]}=du,v?。同樣的剪枝方法見這里。
Code
CF1051F The Shortest Statement
m?n<=20m-n<=20m?n<=20,所以可以看成是一棵樹上掛了幾條邊
樹上求兩點間最短距離用LCA
多出來的邊怎么辦?
找出所有非樹邊的端點記為特殊點,枚舉u,v間路徑過每一個特殊點的情況
(u,v路徑要過非樹邊一定過特殊點,枚舉過點的情況是因為可以用dijkstra)
因為u,v間路徑只有 只過樹邊 和 不是只過樹邊 2種,所以一定不會漏(不保證不重,但沒關系)
Code
CF1120D Power Tree
Blog
Code
總結
以上是生活随笔為你收集整理的图论复习——最小生成树MST的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [集训队作业2018] 复读机(生成函数
- 下一篇: MST(最小生成树)的构造