1. 程式人生 > >實現prim演算法

實現prim演算法

如下找出該圖的最小生成樹 

prim演算法是求解該類問題的一種經典演算法

Prim演算法的基本思路:
將圖中的所有的頂點分為兩類:樹頂點(已經被選入生成樹的頂點)和非樹頂點(還未被選入生成樹的頂點)。首先選擇任意一個頂點加入生成樹,接下來要找出一條邊新增到生成樹,

這需要列舉每一個樹頂點到每一個非樹頂點所有的邊,然後找到最短邊加入到生成樹。依次,重複操作n-1次,直到將所有頂點都加入生成樹中。

演算法實現如下

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 void Prim(int n,int
c[ ][100]) 4 { 5 int lowcost[100];//各非樹頂點到樹頂點集的最短路徑 6 int closet[100];//非樹頂點到樹頂點集的最小邊中相對的頂點 7 bool foot[n+1];//表示是否已經為樹頂點,初始為false 8 memset(lowcost,0,sizeof(lowcost)); 9 memset(closet,0,sizeof(closet)); 10 foot[1]=true;//假設先把1作為初始頂點 11 for(int i=2;i<=n;i++){//假設從節點一開始 12
foot[i]=false; 13 closet[i]=1; 14 lowcost[i]=c[1][i]; 15 } 16 for(int i=1;i<n;i++){ 17 int min=99999; 18 int j=1; 19 for(int k=2;k<=n;k++){//計算非樹頂點到樹頂點集的最短路徑,並把對應頂點記為j 20 if((lowcost[k]<min)&&(foot[k]==false)){
21 min=lowcost[k]; 22 j=k; 23 } 24 } 25 cout <<"選邊"<< "("<<closet[j] << "," <<j<<")" << endl;//把改變歸為已選邊,並把foot[j]設為true 26 foot[j]=true; 27 for(int k=2;k<=n;k++){//由於新的頂點加入樹頂點,所以要更新非樹頂點到樹頂點集的最短路徑lowcost[j],和對應的clost[j] 28 if((c[j][k]<lowcost[k])&&(foot[k]==false)){ 29 lowcost[k]=c[j][k]; 30 closet[k]=j; 31 } 32 } 33 } 34 35 36 } 37 int main() 38 { 39 cout << "請輸入圖的頂點數" << endl; 40 int n; 41 cin >>n; 42 cout << "請輸入圖的邊數" << endl; 43 int m; 44 cin >> m; 45 cout << "請輸入圖的邊的兩個端點和邊的長度" << endl; 46 int c[100][100]; 47 for(int i=1;i<=n;i++){ 48 for(int j=1;j<=n;j++){ 49 c[i][j]=99999; 50 } 51 } 52 int i1,j,k; 53 for(int i=1;i<=m;i++){ 54 cin >>i1 >> j >> k; 55 c[i1][j]=k; 56 c[j][i1]=k; 57 } 58 Prim(n,c); 59 return 0; 60 61 }

執行結果如下