【概念】:
***生成樹:乙個連通圖的生成樹,指的是該圖的乙個子圖(沒有形成迴路),他包含圖的所有結點,但只有把所有結點連線在一起的n-1條必要的邊;
***最小生成樹:乙個連通圖的生成樹中,所有邊的權值加起來最小的生成樹;稱為最小生成樹;
【簡介】:prime演算法可在加權連通圖里搜尋最小生成樹。即:所有邊的權值之和為最小。
prime演算法是圖論中求最小生成樹的一種演算法,與之類似的演算法還有kruskal演算法;
區別:prime演算法適合邊多定點少的圖;
2.dijkstra演算法適合邊少定點多的圖;
要求最小生成樹,當然首先要把圖存進乙個東西中,這樣才能圖對進行搜尋操作。
一般的存圖方式有三種:
1.鄰接矩陣
存圖思想:用乙個矩陣來記錄乙個圖,矩陣第 i 行第 j 列的值就表示頂點 i 到頂點 j 的權值1.2 鄰接表
存圖思想:對每個頂點,使用不定長的鍊錶來儲存從該點出發的所有邊的情況,第 i 個鍊錶的第 j 個值就是頂點 i 到頂點 j 的權值。1.3 鏈式前向星
存圖思想:主要的資料結構是邊陣列(儲存邊的陣列),當然想要完美表示圖,光有乙個邊集陣列還不夠,還要有乙個陣列每乙個點的第一條邊。同時,每一條邊都需要儲存接下來一條邊的「指標」1.2.1 用到的陣列
我寫的這個prime演算法存圖用的是鄰接矩陣。
int mp[n][n]; //使用鄰接矩陣存圖;1.2.2 初始化int dis[n]; //到生成樹的最短距離;
int vis[n]; //標記陣列,標記該結點是否納入集合,即該結點是否訪問過;
int p[n]; //儲存父親結點;
初始化:自己與自己的距離為0,自己與別的結點的距離初始化為無窮大,即,表示不連通;
將所有的結點都標記為為訪問,我這用0表示未訪問,1表示已訪問;
memset(vis, 0, sizeof(vis)); //全部未訪問過無窮大:#define inf 0x3f3f3f3f
void inin(int n)//初始化:mp陣列初始化,vis標記陣列初始化;
}}
1.2.3 prime演算法主體
傳入乙個節點,當然,傳入的這個節點是隨意的。將這個點到其他點的距離存入dis陣列,並將傳入的這個點標記為已訪問。
然後找出從st(傳入的那個點)出發的路徑中的最短的乙個路徑;並將它到達的那個點記性並標記。然後更新dis陣列(重點):如果該結點沒有被訪問過,且點距離當前點的距離更近,就執行更新;最後dis陣列中就是最小生成樹的最短路徑的集合;對其求和,即是最小生成樹的最短路徑;
**實現:
void
prime
(int st,
int n)
//st是任意乙個開始的結點,此節點隨意;
dis[i]
= mp[st]
[i];
} vis[st]=1
;//將該點標記為訪問過;
while(1
)}if(k ==-1
)//所有結點都已訪問;即:已生成最小生成樹;跳出死迴圈;
vis[k]=1
;//將剛才i連線的結點標記為已訪問;
for(i =
1; i <= n; i++
)//更dis陣列,}}
for(i =
1; i <= n; i++
)}
完整的使用鄰接矩陣存圖的prime演算法如下:
#include
#include
using namespace std;
#define n 1000
#define inf 0x3f3f3f3f
int mp[n]
[n];
//使用鄰接矩陣存圖;
int dis[n]
;//到生成樹的最短距離;
int vis[n]
;//標記陣列,標記該結點是否納入集合,即該結點是否訪問過;
int sum =0;
int p[n]
;//父親結點;
void
inin
(int n)
//初始化:mp陣列初始化,vis標記陣列初始化;}}
void
prime
(int st,
int n)
//st是任意乙個開始的結點,此節點隨意;將st看做最小生成樹的根節點
dis[i]
= mp[st]
[i];
} vis[st]=1
;//將該點標記為訪問過;
while(1
)}if(k ==-1
)//所有結點都已訪問;即:已生成最小生成樹;跳出死迴圈;
vis[k]=1
;//將剛才i連線的結點標記為已訪問;
for(i =
1; i <= n; i++
)//更dis陣列,}}
for(i =
1; i <= n; i++)}
void
parent
(int n)
}int
main()
}prime(1
, n)
; cout << sum << endl;
parent
(n);
return0;
}
輸入樣例:
如果傳入的結點是1,那麼,
剛開始的dis陣列如下:當然,你也可以在輸入的時候指定特定點之間的距離:0 0 4 9 21
執行更新之後:
0 0 4 8 16
例:x到y的距離為sp;
x y sp1 2 5
1 3 3
1 4 7
1 5 4
1 6 2
inin
(n);
for(
int i=
1;i<=m;i++
)prim()
;parent()
;
Prime演算法求最小生成樹 鄰接表)
name prime演算法求最小生成樹 鄰接表 author 巧若拙 date 25 11 14 13 38 description 實現了 prime演算法求最小生成樹 鄰接表 的普通演算法和最小堆優化演算法。include include define max 2000 最大頂點數量 defin...
最小生成樹之prime演算法
在這裡我就不擺最小生成樹的定義了,對於最小生成樹,我們必須注意一下兩點 1 盡可能選取權值小的邊,但不能構成迴路。2 選取合適的n 1條邊將聯通圖的n個頂點連線起來。演算法簡單描述 1 輸入 乙個帶權連通圖,其中頂點集合為v,邊集合為e 2 初始化 vnew 其中x為集合v中的任一節點 起始點 en...
最小生成樹 Prime演算法
對於乙個圖,它的所有生成樹中必有乙個 邊的權值最小 的生成樹,我們把它稱為最小生成樹。概念很抽象,換做實際問題 有十個城市,各個城市之間距離或遠或近。需要建設乙個道路網,把十個城市連線在一起,要求道路網的道路長度最小。各個城市的連線可以抽象為乙個圖,本質上即是求該圖的乙個最小生成樹。每乙個圖可能有多...