最小生成樹:對於一個無向連通圖的最小生成樹,選取邊使得圖中每一個頂點連通且花費最小。算法
在kruskal算法中,集合A是一個森林,加入集合A中的安全邊老是圖中鏈接兩個不一樣連通分支的最小權邊。prim算法中,集合A僅造成單顆樹,添加入集合A的安全邊老是鏈接樹與一個不在樹中的頂點的最小權邊。ubuntu
kruskal在圖G(v,e)上的運行時間取決於不相交集合數據結構是如何實現的,模板中採用路徑優化的並查集,時間複雜度爲O(1)。而後對時間複雜度有影響的就是對邊的排序,其最終時間複雜度O(E lgV);安全
prim算法適用於邊多的,反之爲kruskal算法。鑑於kruskal代碼的簡單易操做,例題解法均爲kruskal算法。網絡
Kruskal僞代碼:數據結構
(1)對全部的邊從小到大排序學習
(2)while(n>1) do{優化
取權值最小的邊(u,v);ui
if(u,v不連通){spa
將(u,v)加入T;排序
n--;
}
將邊(u,v)從集合E中刪除;
}
其中判斷兩點是否連通可以使用並查集
模板:kruskal模板代碼
例題及擴展:(所有作完就能夠成爲入門菜鳥了)
基礎例題:
經常使用套路:n個結點的最小生成樹由n-1條邊構成,基礎題通常會提早鏈接好一些點,將這些點加入並查集並計算還需加入多少邊便可
難度:easy
題意:構建最小生成樹,會給出一些已經鏈接好的點。
解析:將給出的已鏈接點提早加入並查集,計算還需加入多少條邊才能構成最小生成樹,而後加邊便可。
代碼:HDU-3371 Connect the cities
難度:easy
題意:構建最小生成樹,使得生成樹的最長邊減去最短邊所得的值最小。
解析:對於全部的邊從小到大排序,每次枚舉一個區間【L,R】,區間長度爲n-1,比較每次的結果求最小值
難度:medium
題意:給一張圖和多個子網,子網已經連通且花費固定,求把圖連通的最小花費)
解析:運用子集生成枚舉子網,每次將子網中的點提早加入並查集,計算還需加入多少條邊才能構成最小生成樹,再構建 生成樹,比較每一次的結果取最小值
繼續學習一些概念:
(1)切割性質。假設全部邊權均不相同。設S爲非空也非全集的V的子集,邊e是一個端點在S中,一個不在的邊中權值最小的,則圖全部的生成樹都包含e
(2)迴路性質。假設全部邊權均不相同。設C爲圖中的任意迴路,邊e是C上權值最大的邊,則圖全部的生成樹不包含e。
增量最小生成樹:從包含n個點的空圖開始,依次加入m條帶權邊。每加入一條邊輸出當前圖的最小生成樹的權值(不連通輸出無解)每次求解完整的最小生成樹的時間複雜度爲O(m^2logn),顯然不行。
可行節點數到達n-1時恰好構成一個最小生成樹,後面繼續加邊則根據迴路性質,加入邊e(u,v)時,找到u到v的惟一路徑上權值最大的邊,與e進行比較,刪除權值較大的邊把其餘全部邊刪除。
最小瓶頸生成樹:給出帶權無向圖,求一顆生成樹,使其最大邊權儘量小。(就是最小生成樹)
最小瓶頸路:給出帶權無向圖,求u到v的一條路徑,使得路徑上的最長邊儘可能短。求最小生成樹,起點終點都在樹上的惟一路徑就是要找的路徑(uva10048)
最小瓶頸路最大邊長:求出最小生成樹,用dfs將其轉化爲有根樹,計算maxcost【u】【v】,從v出發訪問一個新節點u時,考慮全部已經訪問過的結點x maxcost【x】【u】=max(maxcost【x】【v】,maxcost【v】【u】),複雜度爲O(n^2)
次小生成樹:若是最小生成樹不惟一,則次小生成樹的權值與最小生成樹相同。
枚舉要加入哪一條新邊,最小生成樹加入邊u-v後,圖中會出現一條迴路,因此要刪除的邊在最小生成樹u到v的路徑上,並且是這條路徑的最長邊。即次小生成樹一點能夠由最小生成樹加一條邊,刪去一條邊獲得。
因此只須要按照「每對結點間的最小瓶頸路」求出每對結點在最小生成樹惟一路徑上的最長邊maxcost【u】【v】
生成樹變種類型的問題:
難度:medium easy
題意:給出網絡和某些特定的點,刪除網絡上的邊使得這些特定點之間兩兩互不不連通,且花費最小。
解析:構建最大生成樹(邊按從大到小排序後執行kruskal算法),當一條邊的兩端點都是給定的點時,花費加上這條邊, 反之加入最大生成樹。最後獲得的是多個包含一個給定點的最大生成樹(一個端點也能夠看作),最大生成樹之間 不相連,本身思考一下爲何達到了題目的條件)
難度:medium
題意:城市有人口總數,城市之間有道路,將城市鏈接起來的花費爲B。你能夠免費鏈接兩個城市,免費鏈接的兩個城市人 口之和爲A。找一個使得A/B最大的方案
解析:先求出最小生成樹,枚舉u,v並刪除最小生成樹中u,v鏈接路徑上邊長最長的邊,比較沒種狀況的結果