對於無向圖g=(v, e),v
表示圖中的結點,
e表示圖中的邊,所謂最小生成樹就是聯通圖
g中所有結點所需要的邊長度總和最小,這些邊加上
v就構成圖
g的一顆最小生成樹。這樣還不清楚我們可以舉個例子:有
n個城市分布在不同的地方,為了保證每個城市間都能用火車通行,我們需要在城市之間修鐵路,但是為了節約成本,我們在保證每兩個城市之間都能聯通的情況下要使得所修的鐵路長度最短。這就是乙個最小生成樹的問題
2、如何求出無向圖g=(v, e)
的一棵最小生成樹呢?
假設a是某棵最小生成樹的子集,下一步我們需要做的就是找出一條邊
(u,v)
,將其加入到
a中,使得a∪
也是某棵最小生成樹的子集
,我們稱
(u,v)
為安全邊。
用下列偽**來表示獲得一棵最小生成樹的過程
a=null
while a 還不是一棵完整的最小生成樹
}return a //此時
a已經是一棵最小生成樹
很顯然難點在與如何尋找a
的安全邊。
3、如何需找a的安全邊?
在尋找安全邊之前我們需要介紹介幾個概念:
切割(s,v-s):對集合v的乙個劃分,將集合v劃分為兩個部分s和v-s
橫跨切割:若邊(u,v)的乙個節點屬於s另乙個節點屬於v-s,則稱(u,v)橫跨切割
尊重集合a:如果a中不存在橫跨切割的邊,則稱該集合尊重集合a
設(s,v-s)是圖g中尊重a的任意乙個切割,(u,v)是橫跨切割(s,v-s)的輕量級邊。我們可以證明(u,v)是a的一條安全邊
證明:設t是一棵包含a的最小生成樹,並假定t不包括(u,v),若t包括(u,v)則可以直接說明(u,v)是安全的,現在我們需要構建一棵最小生成樹t2包含a∪,從而證明(u,v)對於a是安全的。具體如何構造t2如下:
我們可以找到另外一條橫跨切割(s,v-s)的邊(x,y)且(x,y)屬於樹t,由於該切割尊重集合a,所以(x,y)不在集合a中,所以可以構造一棵新樹t2=t-∪。下面證明t2為最小生成樹,設w(t)為t中所有邊的權重和w(u,v)為邊(u,v)的權重,則w(t2)=w(t)-w(x,y)+w(u,v)<=w(t),所以t2也是一棵最小生成樹
最終證明了橫跨尊重集合a的切割(s,v-s)的一條輕量級邊(u,v)為a的一條安全邊
有關求最小生成樹的演算法prim和kruskal請參照最小生成樹演算法prim、kruskal
最小生成樹詳解
鏈式前向星 學習筆記 一 prim演算法 普通prim演算法模板 用前向星錄資料的時候記得把head初始化為 1 fill dist,dist len,max memset vis,0,sizeof vis int ans 0 dist 1 0 如果題目要求輸出最小生成樹,就把題目要求的源點s的di...
最小生成樹(詳解)
最小生成樹和最短路還是區別很大的,所以又雙叒來寫了。最小生成樹問題顧名思義,概括來說就是路修的最短。接下來引入幾個一看就明白的定義 帶權圖 邊賦以權值的圖稱為網或帶權圖,帶權圖的生成樹也是帶權的,生成樹t各邊的權值總和稱為該樹的權。最小生成樹 mst 權值最小的生成樹。最小生成樹的性質 假設g v,...
Prim演算法生成最小生成樹詳解
建立乙個low陣列代表相應每個節點連線所需最小費用,乙個vis陣列標記相應節點是否連線過。low陣列的初始值用節點1到其餘各點的費用來填充 如該圖所示low陣列的初始值應該為 0634 5以上便是1號節點對於其他各點的費用 接下來在low陣列中尋找最小值 為3號節點費用為3最小。接著以3號節點為起始...