最小生成樹及最大生成樹(算法及正確性簡單證明)


最小生成樹

kruskal

kruskal算法步驟:

  1. 將所有邊按權值從小到大排序
  2. 將邊按序加入最小生成樹
    a. 如果該邊連接的兩點已經屬於一個集合,則舍棄該邊
    b. 如果該邊連接的兩點不屬於一個集合,則加入該邊,並將所連兩點用並查集合並
  3. 當加入n-1條邊后得到的就是該圖的最小生成樹

這么做時間復雜度為\(O(M\log M)\),M為邊的總數,這是給所有邊按權排序的時間復雜度,之后並查集的時間復雜度我不太清楚,大概在\(O(N\log N)\)
這里用到了貪心思想,也許你會懷疑:為什么這么做是對的?
證明應該分為兩部分:首先證能連成樹,再證這種連法是權值最小的。
首先第一部分十分顯然,一個n個點的連通圖一定能連成一棵樹。
主要來看第二部分:
如果當前邊連接的兩點不在一個集合里,按照kruskal算法應該加入該邊,我們假設舍棄會有更好的結果,最后得到一棵不含該邊的最小生成樹,我們此時再把該邊加入,一定會出現一個環,在該環上不可能所有邊比這條邊小,如果所有邊比這條邊小,那么會與我們在加入該邊時這兩個點時不連通情況矛盾,那么這個環上一定有邊的權值是大於等於該邊的,如果我們用這條邊把權值大於等於該邊的邊替換,得到的生成樹權值不會大於原生成樹,所以能加入時加入這一策略是對的。由此證明了貪心的正確性。

prim

prim算法步驟我懶得寫了,提一嘴時間復雜度是\(O(N\log N)\),接着我簡單證明一下正確性吧
prim算法也是運用貪心的思想。要證明prim算法是對的,關鍵是要證,對於一個集合,離集合最近的邊一定是在最小生成樹上。
算了,懶得證了,哪天有時間再補吧

最大生成樹

顧名思義,最大生成樹就是權值最大的生成樹。
我們很容易想到:按照最小生成樹的做法反過來做不就好了?
但這樣對嗎?
按照以上最小生成樹貪心正確性的證明,我認為這樣是對的。
當然,有一種更保險的做法,把所有邊邊權改為\(X-W\)\(X\)是我們賦的一個很大的數,再跑一遍最小生成樹,得到的結果是\(X*(N-1)-\sum W\),因為\(X*(N-1)\)是一個常數,所以減去該常數取反得到的一定是最小生成樹權值和。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM