*本題的kruskal解法
題目描述:
給定村莊數n,用字母表的前n個字母表示,接下來n-1行每行乙個村莊字母和與其連線的村莊數以及各村莊的字母和距離。求最小生成樹。
解題思路:
先說明一下prim演算法:
普里姆演算法(prim演算法),圖論中的一種演算法,可在加權連通圖里搜尋最小生成樹。意即由此演算法搜尋到的邊子集所構成的樹中,不但包括了連通圖里的所有頂點(英語:vertex (graph theory)),且其所有邊的權值之和亦為最小
我們假設5個點a,b,c,d,e 其互相的關係(邊的權值)為以下矩陣(二維陣列),然後簡單寫幾個邊
side(a,b)=side(b,a)=1 //ab的邊權值 為1 prim適用於無向圖,所以記得雙向賦值
side(a,c)=side(c,a)=2
side(a,e)=side(e,a)=5
side(b,e)=side(b,a)=3
side(c,d)=side(d,c)=4
我們填充一下陣列,因為求最小的生成樹,所以本身(a,a)我們設為0,沒有連線的我們設為m(max)ab
cdea
012m
5b10
mm3c
2m04
mdmm
40me
53mm
0 我們看一下如何連通這些點,首先以第乙個為起點(反正所有的點我們都要連線)
與a最近的點即b,我們可以這樣想,如果其他的點都連線起來了,那麼肯定也是以ab邊去連線a,所以ab邊必不可少。
當ab連線了之後,我們將b與其他點的狀態與a共享,也就是,原來a連線不到的(或權值較大的),可以通過b作為橋梁去連線。
我們重新整理一下該陣列ab
cdea
012m
3b10
mm3c
2m04
mdmm
40me
33mm
0 我們看到,ae的邊 發生了變化,因為原有的ae=5權值大於ab,所以當我們選擇連線e的時候,我們更傾向於通過b連線,也就等同於a連線。
或者我們可以把a看作(a,b)集合。然後我們再找與其邊最小的點(c)ab
cdea
0124
3b10
mm3c
2m04
md4m
40me
33mm
0 然後連線e,最後d。
所以我們的操作實際上就是不斷的重新整理維護第一列(行)陣列。當然,為了清晰,我們也可以把其單獨摘出來,或者用佇列記錄這乙個集合等處理方式
#include#include#define inf 99999999
int v_nmapvalue[30][30];
int v_nminans;
int n;
int fmin(int a,int b)
{ return a
最小生成樹(prim和kruskal)
建圖之後,首先對邊的權值排序,每次取出沒有被選中並且最小的邊,用並查集判斷邊的兩點是否相連,如果相連則跳過找下乙個點,否則連線著兩個點,當連線的邊數等於點數 1時,就找到了最小生成樹。例題 networking poj 1287 include include include define max ...
最小生成樹 Prim和Kruskal
首先這是圖的最小生成樹 加權圖 在學習最小生成樹之前需要先明確幾個重要概念。1 連通圖 在無向圖中,若任意兩個頂點與都有路徑相通,則稱該無向圖為連通圖。2 強連通圖 在有向圖中,若任意兩個頂點與都有路徑相通,則稱該有向圖為強連通圖。3 連通網 在連通圖中,若圖的邊具有一定的意義,每一條邊都對應著乙個...
最小路徑和
給定乙個只含非負整數的m n網格,找到一條從左上角到右下角的可以使數字和最小的路徑。注意事項 你在同一時間只能向下或者向右移動一步 這道題和之前做的一道三角形的動態規劃差不多,但是更難一些,例a b c d e f g h i 如果要到i就必須從f 或h走,只要選出其中較小的即可,再用遞迴算出走每乙...