關於最小生成樹的一些理解

2021-09-06 04:16:13 字數 4444 閱讀 2485

***

(1)

定義在一棵樹裡新增一條邊,並在產生的圈裡刪除一條邊叫做一次操作。(也就是說換掉一條邊並且保證結果是樹),則樹a和b是無向圖的兩個生成樹,則a可以通過若干次操作變成b。

證:把樹看作邊的集合,如果b中有一條a沒有的邊,則把這條邊加到a上,a產生乙個圈中至少有一條是b中沒有的邊,把這條邊刪掉,則a仍然是生成樹,a,b集合相同的邊多了一條,重複這個過程直到a b包含的邊相同。

注:這個命題比較容易證,它告訴我們任何兩棵生成樹都可以通過不斷換邊得到。(重要的是換邊的過程中始終保持是樹。)

「可以通過若干次操作」,這個「可以」並沒有「特殊」的含義,也就是說我們可以隨便加一條b有而a沒有的邊,總可以找到一條合適的邊刪掉。

(2)

把乙個連通無向圖的生成樹邊按權值遞增排序,稱排好序的邊權列表為有序邊權列表,則任意兩棵最小生成樹的有序邊權列表是相同的。(演算法導論23.1-8)

證:設最小生成樹有n條邊,任意兩棵最小生成樹分別稱為a, b, 如果e是一條邊,用w(e)表示該邊的權值。

a的邊按權值遞增排序後為a1, a2,……an   w(a1)≤w(a2)≤……w(an)

b的邊按權值遞增排序後為b1, b2,……bn  w(b1)≤w(b2)≤……w(bn)

設i是兩個邊列表中,第一次出現不同邊的位置,ai

≠bi不妨設w(ai)≥w(bi)

情形1  如果樹a中包含邊bi

,則一定有j>i使得bi=aj ,事實上,這時有 w(bi)=w(aj)≥w(ai) ≥w(bi) 故 w(bi)=w(aj)=w(ai),在樹a的邊列表中交換邊ai

和 aj

的位置並不會影響樹a的邊權有序列表,兩棵樹在第i個位置的邊變成同一條邊。

情形2  樹a中並不包含邊bi

,則把bi

加到樹a上,形成乙個圈,由於a是最小生成樹,這個圈裡任意一條邊的權值都不大於w(bi) ,另外,這個圈裡存在邊aj

不在樹b中。因此,有w(aj)≤w(bi),且j>i (因為aj

不在b中)。於是,有w(bi)≤w(ai)≤w(aj)≤w(bi),因此

w(ai)= w(aj) = w(bi)。那麼在樹a中把aj

換成bi

仍然保持它是一棵最小生成樹,並不會影響樹a的邊權有序列表,並且轉換成情形1。

注:這個命題說明,如果無向圖的邊權都不相同,則最小生成樹是唯一的。但是其逆命題不成立。即如果無向圖的最小生成樹唯一,則無向圖的邊權是可能有相同的。例子,比如原圖本身就是一棵樹,並且有兩條邊的邊權相等。

(3)

a,b是同乙個無向連通圖的兩棵不同的最小生成樹,則a可以通過若干次(1)中定義的換邊操作,並且保證每次結果仍然是最小生成樹,最終轉換成b。

證:做法和(2)類似,也是要找一條樹b有但是樹a沒有的邊。事實上(2)的證明過程「情形2」的部分,就已經找到這樣一條邊了。按照(2)中給出的方法,就可以把a轉換成b。

注:上述證明過程證得了和(1)中類似的結論,但是此時的「可以」暫時有「特殊」的含義,至少證明中需要以一定的規則選邊。這顯得有點不「美觀」。那麼,是否可以任意選邊呢?考慮任意選邊造成的「後果」:把任意一條b有而a沒有的邊加入到a,由於a是最小生成樹,所以形成的圈裡所有的邊的權值都不大於新加的邊,那麼如果這個圈裡沒有其他的這種權值的邊,換句話說,如果這個圈裡的這條邊是唯一權值最大的邊怎麼辦呢?或者,如果這個圈裡所有和這條邊權值相等的邊都也在b中,那麼該如何保證換邊後,a和b相同的邊數增多一條呢?下面證明,這些情況不可能出現。

(4)

乙個連通無向圖g,不會有一棵最小生成樹包含g的乙個圈中全部最大權值的邊。

證:設圖的節點集合是v。反證,假設有一棵最小生成樹t包含g中某個圈的全部權值最大的邊,設其中一條邊是e, 則在樹中刪掉邊e,t-e是不連通的,它把節點分成了兩部分(連通分量),a和b=v-a。在原圖g中,這條邊在乙個圈c裡,且在c中權值是最大的。則(c-e)是g中一條路,這條路中有節點在a中,也有節點在b中,因此必然有一條邊e』,它一端在a中,一端在b中,顯然它不在t-e中。於是把e』加入到t-e中,這樣形成的是一棵樹t』。(|v|-1條邊的連通圖顯然是樹),而由於w(e』),有w(t』),與t是最小生成樹矛盾。

注:特別地,如果乙個圈中權值最大的邊唯一,則最小生成樹不包含這條邊。

(演算法導論上習題23.1-5要證明:如果一條邊是乙個圈中權值最大的邊,一定有一棵最小生成樹不包含它。由這個結論可以立刻得出。當圈中最大權值的邊唯一時,演算法導論上這個命題稍弱。)

至此證明了任何兩棵不同的最小生成樹a,b,可以隨意選一條b有而a沒有的邊,新增到a上,由(4)的結論,形成的圈裡,至少有一條邊和這條新加的邊權值相同,並且它不在b中,刪掉它。這樣可以最終把a轉化成b。

(5)

對於乙個連通無向圖的生成樹,只考慮它的邊權,形成的有序邊權列表中,最小生成樹是有序邊權列表字典序最小的。(字典序就是通常的定義,兩個序列a,b的字典序相同當且僅當a=b。否則,序列a,b出現最早位置的不相等的元素時,如果序列a的該位置元素更小,則序列a字典序小,反之,則序列b的字典序更小。如果直到乙個序列結束都沒有這樣的位置,則較短的序列字典序小)。

證:設a是一棵最小生成樹,而b是不是一棵最小生成樹。利用(2)的結論,因為任何最小生成樹的有序邊權列表是相同的,所以可以用krusal演算法產生的最小生成樹的有序邊權列表。krusal演算法的優點是按邊權順序加邊,並且當邊權相等時,只要不形成圈,加哪條邊都可以形成最小生成樹。把b的邊都按遞增順序排序:

b的邊按權值遞增排序後為b1, b2,……bn  w(b1)≤w(b2)≤……w(bn)

用krusal演算法求原圖的一棵最小生成樹,

具體地,加第i條邊時(1≤i≤n),如果對該加的邊e,有w(e)=w(bi),則選擇bi

代替e加入。不可能出現w(e)>w(bi),因為krusal演算法是按邊權由小到大考慮加邊的,如果出現這種情況,說明,選擇bi

加入是不合法的——會形成圈,而此時的圖是樹b的子圖,這與b是樹矛盾。

注:有了(2)的結論,結合krusal演算法的過程,知道krusal演算法加邊的順序構成的邊權列表就是乙個有序邊權列表。於是,只考慮有序邊權列表時,可以用krusal演算法產生的特殊的最小生成樹代替任何一棵最小生成樹。

如果一棵樹是最小生成樹,則對它採取一次(1)中的操作,顯然,它的總權值不減。那麼它的逆命題是不是成立?也就是如果說一棵生成樹,對它採取一次(1)中的操作後,它的總權值不減,它是否是最小生成樹?再換句話說,一棵非最小生成樹,是否一定可以找到一條邊進行(1)中的操作後,總權值會減小?這個命題看起來是顯然的,但是是否有可能一棵非最小生成樹當前無論怎樣採取(1)中的操作都會造成總權值暫時的增大,而至少要操作兩次,才能把權值降低呢?答案是不會的。

(6)

一棵樹不是最小生成樹,則一定存在乙個(1)中描述的操作,使得操作之後,它的總權值減小。

證:設a不是最小生成樹,a的邊按權值遞增排序後為a1, a2,……an   w(a1)≤w(a2)≤……w(an)。利用krusal演算法,加第i條邊時(1≤i≤n),如果對該加的邊ei

,有w(ei)=w(ai),則選擇ai

代替ei

加入。直到第j次時(1≤j≤n),有w(ej)j),則仍加入ej,自此後仍執行普通的krusal演算法(即任意處理權值相同的邊),這樣生成的最小生成樹e,有w(ej)j) 且對所有1≤i有ei=ai

,由於權值遞增關係,ej

不在a中,那考慮把ej

加入到a中形成的圈,圈裡其他任意的邊ax,若w(ax)≤w(ej)j),則有x,於是這些邊是在第j步之前和krusal演算法一樣加入的。因此,圈裡至少有一條邊ay

滿足w(ay)≥w (aj)>w(ej) (y≥j>x),於是刪除ay

可以讓a的總權值減小。

注:可見確實有這樣的操作。於是立刻得出以下結論:

(7)

一棵生成樹不是最小生成樹,則一定存在(1)中的操作,不斷進行把它轉換成一棵最小生成樹,而且每次操作后權樹的總權值都會減小。

證:由(6)知,存在乙個這樣的操作,任選乙個這樣的操作,總權值會減小。這樣不斷地進行下去,因為不同的生成樹的個數是有限的,所以總權值不可能一直減小下去,也不可能無限逼近與乙個常數,最終可以使其變成一棵最小生成樹。

注:由此可知,這種操作也是「任意」選邊的,並沒有特殊性。如果把乙個圖的所有生成樹看作節點,把對每個生成樹進行一次(1)中定義操作看作形成的樹作為它的鄰居。

那麼綜合上述結論:形成的圖是個無向連通圖。任何「區域性最優解」也是「全域性最優解」(只進行一次操作不能減小總權值,則是最小生成樹,可以隨意從任何乙個「非最優點」,保持權值減小地逐步達到「最優點「)。

(8)

如果一棵生成樹,任何邊都在某棵最小生成樹上,則它不一定是最小生成樹。

反例:考慮乙個長為2,寬為1的矩形。構造乙個無向圖,節點就是矩形頂點,邊就是矩形的邊,邊權就是矩形邊長。顯然,原圖有兩棵最小生成樹(「兩寬與一長」),所有邊都在某棵最小生成樹上,但是有兩棵生成樹不是最小生成樹(「兩長與一寬」)。

【**】

關於最小生成樹

乙個有n個結點的連通圖的生成樹是原圖的極小連通子圖,且包含原圖中的所有n個結點,並且有保持圖連通的最少的邊。一般是用並查集的合併與查詢操作來支撐的,這裡簡單提一下 先定義乙個陣列 fa i 表示 i 的父節點 inline int find int x 查詢祖先inline void merge i...

最小生成樹(一)

kruscal 演算法 include include includeusing namespace std int per 105 n struct node 結構體來儲存邊 x 5005 bool cmp node a,node b void init 初始化操作 int find int x ...

關於最小生成樹(一) prim演算法

時間限制 1000ms 長度限制 10kb 提交次數 0 通過次數 0 題型 程式設計題 語言 g gcc vc description 給定結點數為n,邊數為m的帶權無向連通圖g,所有結點編號為1,2,3 n。求圖g的最小生成樹的邊權和。輸入格式 第一行兩個正整數n和m。n,m 2000 之後的m...