最小生成樹(普利姆演算法、克魯斯卡爾演算法)
設G = (V,E)是無向連通帶權圖,即一個網路。E中的每一條邊(v,w)的權為c[v][w]。如果G的子圖G’是一棵包含G的所有頂點的樹,則稱G’為G的生成樹。生成樹上各邊權的總和稱為生成樹的耗費。在G的所有生成樹中,耗費最小的生成樹稱為G的最小生成樹。構造最小生成樹的兩種方法:Prim演算法和Kruskal演算法。
一、最小生成樹的性質
設G = (V,E)是連通帶權圖,U是V的真子集。如果(u,v)∈E,且u∈U,v∈V-U,且在所有這樣的邊中,(u,v)的權c[u][v]最小,那麼一定存在G的一棵最小生成樹,它意(u,v)為其中一條邊。這個性質有時也稱為MST性質。
二、Prim演算法
設G = (V,E)是連通帶權圖,V = {1,2,…,n}。構造G的最小生成樹Prim演算法的基本思想是:首先置S = {1},然後,只要S是V的真子集,就進行如下的貪心選擇:選取滿足條件i ∈S,j ∈V – S,且c[i][j]最小的邊,將頂點j新增到S中。這個過程一直進行到S = V時為止。在這個過程中選取到的所有邊恰好構成G的一棵最小生成樹。
如下帶權圖:
生成過程:
1 -> 3 : 1
3 -> 6 : 4
6 -> 4: 2
3 -> 2 : 5
2 -> 5 : 3
實現:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
三、Kruskal演算法
當圖的邊數為e時,Kruskal演算法所需的時間是O(eloge)。當e = Ω(n^2)時,Kruskal演算法比Prim演算法差;但當e = o(n^2)時,Kruskal演算法比Prim演算法好得多。
給定無向連同帶權圖G = (V,E),V = {1,2,...,n}。Kruskal演算法構造G的最小生成樹的基本思想是:
(1)首先將G的n個頂點看成n個孤立的連通分支。將所有的邊按權從小大排序。
(2)從第一條邊開始,依邊權遞增的順序檢查每一條邊。並按照下述方法連線兩個不同的連通分支:當檢視到第k條邊(v,w)時,如果端點v和w分別是當前兩個不同的連通分支T1和T2的端點是,就用邊(v,w)將T1和T2連線成一個連通分支,然後繼續檢視第k+1條邊;如果端點v和w在當前的同一個連通分支中,就直接再檢視k+1條邊。這個過程一個進行到只剩下一個連通分支時為止。
此時,已構成G的一棵最小生成樹。
Kruskal演算法的選邊過程:
1 -> 3 : 1
4 -> 6 : 2
2 -> 5 : 3
3 -> 4 : 4
2 -> 3 : 5
實現:
![](http://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
參考書籍 《演算法設計與分析(第二版)》 王曉東