1. 程式人生 > 其它 >Prim演算法實現最小生成樹

Prim演算法實現最小生成樹

  Prim演算法的基本思想是對圖G(V,E)設定集合S來存放已被訪問的頂點,然後執行n次下面的步驟。

  (1)每次從集合V-S中選擇與集合S最近的一個頂點,訪問u並將其加入集合S,同時把這條集合S最近的邊加入最小生成樹中。

  (2)令頂點u作為集合S與集合V-S連線的介面,優化從u能到達的未訪問頂點v與集合S的最短距離。

程式碼:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 const int MAXV = 1000;  //最大頂點數 
 5 const int INF = 100000000
; 6 7 int n,m,G[MAXV][MAXV]; //n為頂點數,MAXV為最大頂點數 8 int d[MAXV]; //頂點與集合S的最短距離 9 bool vis[MAXV] = {false}; //標記陣列 10 11 int prim(){ 12 fill(d,d+MAXV,INF); 13 d[0]=0; //只有0號頂點到集合S的距離為0,其餘全為INF 14 int ans=0; //最小生成樹邊權之和 15 for(int i=0;i<n;i++){ 16 int u=-1,MIN=INF; //u使d[u]最小,MIN存放該最小的d[u]
17 for(int j=0;j<n;j++){ //找到未訪問的頂點中d[]最小的 18 if(vis[j]==false&&d[j]<MIN){ 19 u=j; 20 MIN=d[j]; 21 } 22 } 23 //找不到小於INF的d[u],則剩下的頂點和集合S不連通 24 if(u==-1) 25 return -1; 26 vis[u]=true
; 27 ans+=d[u]; 28 for(int v=0;v<n;v++){ 29 //v未訪問&& u能到達v &&以u為中介點可以使v離集合S更近 30 if(vis[v]==false&&G[u][v]!=INF&&G[u][v]<d[v]){ 31 d[v]=G[u][v]; 32 } 33 } 34 } 35 return ans; 36 } 37 int main() 38 { 39 int u,v,w; 40 cout<<"請輸入頂點個數和邊數:"<<endl; 41 cin>>n>>m; //頂點個數 邊數 42 cout<<"輸入u,v和邊權:"<<endl; 43 fill(G[0],G[0]+MAXV*MAXV,INF); 44 for(int i=0;i<m;i++){ 45 cin>>u>>v>>w; //輸入u,v,邊權 46 G[u][v]=G[v][u]=w; 47 } 48 cout<<"最小生成樹邊權之和為:"<<prim()<<endl; 49 return 0; 50 }

測試結果: