Prim演算法實現最小生成樹
阿新 • • 發佈:2021-06-15
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 }
測試結果: