淺談最大生成樹


一、什么是最大生成樹:

  在一個圖的所有生成樹中邊權值和最大的生成樹即為最大生成樹。

二、怎么生成:

  1、將圖中所有邊的邊權變為相反數,再跑一遍最小生成樹算法。相反數最小,原數就最大。

  2、修改一下最小生成樹算法:對於kruskal,將“從小到大排序”改為“從大到小排序”;

                對於prim,將“每次選到所有藍點代價最小的白點”改為“每次選到所有藍點代價最大的點”。

   證明:對於修改后的kruskal,可以參照:kruskal算法證明及實現,下面是我個人應“最大生成樹”的修改版: 

證明如下:

 

假設最大生成樹樹為U。先做出如下假設:

 

1)按照算法得到的樹為T。

 

2)U和T中不同的邊的條數為k,其它n-1-k條邊相同,這n-1-k條邊構成邊集E;

 

3)在T中而不在U中的邊按代價從大到大依次為a1,a2,...,ak。

 

4)在U中而不在T中的邊按代價從大到小依次為x1,x2,...,xk。

 

現在我們通過把U轉換為T(把T的邊依次移入U中),來證明U和T具有相同代價。

 

首先,我們將a1移入U中,由於U本身是一棵樹,此時任意加一條邊都構成回路,所以a1的加入必然產生一條回路,且這條回路必然包括x1,x2,...,xk中的邊。(否則a1與E中的邊構成回路,而E也在T中,這與T中無回路矛盾。)

 

在這個回路中刪除屬於x1,x2,...,xk且代價最小邊xi構成一個新的生成樹V。

 

假設a1代價大於xi,則V的代價大於U,這與U是最大代價樹矛盾,所以a1不可能大於xi。

 

假設a1代價小於xi,按照修改版的Kruskal算法,首先考慮代價大的邊,則執行算法時,xi應該是在a1之前考慮,而a1又在a2,...,ak之前考慮,所以考慮xi之前,T中的邊只能是E中的邊,而xi既然沒加入樹T,就說明xi必然與E中的某些邊構成回路,但xi和E又同時在U中,這與U是生成樹矛盾,所以a1也不可能小於xi。

 

因此,新得到的樹V與U具有相同代價。即V也為最小生成樹,不過V比U更“靠近”T(不同的邊更少),這時讓U代表現在的V,再走一遍上面的流程, 把a1,a2,...,ak的邊逐漸加到U中,最終得到的樹即為T,且與U代價相同。

 

證明結束。

 

      對於修改后的prim,可以參照:Prim算法和Kruskal算法的正確性證明(參照一下就好),下面是我個人的簡單證明:

prim算法之所以可行,是基於這樣一個判斷:對於任意一個頂點vi,連接到該頂點的所有邊中的一條最短邊(最大生成樹則為最長邊)(vi, vj)必然屬於最小生成樹(最長邊必然屬於最大生成樹)(該判斷也可以擴展成:任意一個屬於最小(或大)生成樹的連通子圖(子樹),從外部連接到該連通子圖的所有邊中的一條最短邊(或最長邊)必然屬於最小(或大)生成樹
 證明如下(這里以最大生成樹為例):設當前點為u,連接到該點所有邊中最長邊的一條為a,用反證法證明,假設最長邊不在最大生成樹U中:
        若把a再加到最大生成樹中,必然會成環。此時在這個環上必然有兩條邊連接着u,一條邊為a(剛加進去),設另一條邊為b,顯然b的權值小於a(因為b不是最長邊,所以b的權值不會等於a),那么把b從環中刪去,得到的生成樹的權值和會比U更大,與U是最大生成樹矛盾。
        對於一個已知點的連通子圖(子圖點之間的邊不重要,因為不會影響子圖與外部鏈接的最長邊),仍用反證法證明,假設與外部連接的最長邊不在最大生成樹U中:
        設該子圖與外部連接的最長邊的一條為a,把a加到最大生成樹中,必然會形成環,環上必然有兩條邊連接着這個子圖,一條邊為a,設另一條為b,則b的權值小於a,那么把b從環里刪去,新得到一個生成樹的權值比U更大,與U是最大生成樹矛盾。
 
  
  
 
 
 
 

 

 

 

 

 


免責聲明!

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



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