問題提出:
要在n個城市間建立通訊聯絡網。頂點:表示城市,權:城市間通訊線路的花費代價。希望此通訊網花費代價最小。
問題分析:
答案只能從生成樹中找,因為要做到任何兩個城市之間有線路可達,通訊網必須是連通的;但對長度最小的要求可以知道網中顯然不能有圈,如果有圈,去掉一條邊後,並不破壞連通性,但總代價顯然減少了,這與總代價最小的假設是矛盾的。
結論:希望找到一棵生成樹,它的每條邊上的權值之和(即建立該通訊網所需花費的總代價)最小 —— 最小代價生成樹。
構造最小生成樹的演算法很多,其中多數演算法都利用了一種稱之為 mst 的性質。
mst 性質:設 n = (v, e) 是乙個連通網,u是頂點集 v的乙個非空子集。若邊 (u, v) 是一條具有最小權值的邊,其中u∈u,v∈v-u,則必存在一棵包含邊 (u, v) 的最小生成樹。
(1)普里姆 (prim) 演算法
演算法思想:
①設 n=(v, e)是連通網,te是n上最小生成樹中邊的集合。
②初始令 u=, (u_0∈v), te=。
③在所有u∈u,u∈u-v的邊(u,v)∈e中,找一條代價最小的邊(u_0,v_0 )。
④將(u_0,v_0 )併入集合te,同時v_0併入u。
⑤重複上述操作直至u = v為止,則 t=(v,te)為n的最小生成樹。
**實現:
void minispantree_prim(mgraph g,vertextype u)
//用普里姆演算法從第u個頂點出發構造網g的最小生成樹t,輸出t的各條邊。
//記錄從頂點集u到v-u的代價最小的邊的輔助陣列定義;
//closedge[j].lowcost表示在集合u中頂點與第j個頂點對應最小權值
closedge[k].lowcost = 0;
//初始,u = ;
printclosedge(closedge,g.vexnum);
for (i = 1; i < g.vexnum; ++i) \
//選擇其餘g.vexnum-1個頂點,因此i從1開始迴圈}}
}
(2)克魯斯卡爾 (kruskal) 演算法
演算法思想:
①設連通網 n = (v, e ),令最小生成樹初始狀態為只有n個頂點而無邊的非連通圖,t=(v, ),每個頂點自成乙個連通分量。
②在 e 中選取代價最小的邊,若該邊依附的頂點落在t中不同的連通分量上(即:不能形成環),則將此邊加入到t中;否則,捨去此邊,選取下一條代價最小的邊。
③依此類推,直至 t 中所有頂點都在同一連通分量上為止。
最小生成樹可能不惟一!
最小生成樹 次小生成樹
一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...
最小生成樹
package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...
最小生成樹
define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...