MST(Minimum Spanning Tree,最小生成樹)問題有兩種通用的解法,Prim算法就是其中之一,它是從點的方面考慮構建一顆MST,大致思想是:設圖G頂點集合為U,首先任意選擇圖G中的一點作為起始點a,將該點加入集合V,再從集合U-V中找到另一點b使得點b到V中任意一點的權值最小,此時將b點也加入集合V;以此類推,現在的集合V={a,b},再從集合U-V中找到另一點c使得點c到V中任意一點的權值最小,此時將c點加入集合V,直至所有頂點全部被加入V,此時就構建出了一顆MST。因為有N個頂點,所以該MST就有N-1條邊,每一次向集合V中加入一個點,就意味着找到一條MST的邊。
原文鏈接:https://blog.csdn.net/yeruby/article/details/38615045
下面用圖和代碼來解釋:
我們首先定義一個數組:lowcost[i];我們初始將V1作為起點,那么lowcost[2] = 6,lowcost[3] = 1,lowcost[4] = 5,lowcost[5] = inf,lowcost[6] = inf;(其中inf=0x7ffffff,i指的是以i為終點的路徑的長度,若沒有一步可達的路徑那么就賦值為inf)
我們明顯可以看出,以V3為終點的路徑最短那么就將V3加入集合V中,lowcost[2]=5,lowcost[3]=0,lowcost[4]=5,lowcost[5]=6,lowcost[6]=4,
將lowcost[3]標記為0,說明V3已經加入到集合V中了。 同時在這里更新以V3為起點所能直接到達的點的最短路。
此時,因為點V6的加入,需要更新lowcost數組
lowcost[2]=5,lowcost[3]=0,lowcost[4]=2,lowcost[5]=6,lowcost[6]=0
明顯看出,以V4為終點的邊的權值最小=2
此時,因為點V4的加入,需要更新lowcost數組:
lowcost[2]=5,lowcost[3]=0,lowcost[4]=0,lowcost[5]=6,lowcost[6]=0
重復執行直到所有點都加入集合V;
#include <iostream>
#define Max 100
#define MaxCost 0x7fffffff
using namespace std; int Graph[Max][Max]; void prime(int n) { int lowcost[Max]; ; int i, j, min1, minid, sum = 0; for (i = 2; i <= n; i++) { lowcost[i] = Graph[1][i]; } mst[1] = 0; for (i = 2; i <= n; i++) { min1 = MaxCost; minid = 0; for (j = 2; j <= n; j++) { if (lowcost[j] < min1 && lowcost[j] != 0) { min1 = lowcost[j]; } } sum += min1; lowcost[minid] = 0; for (j = 2; j <= n; j++) { if (Graph[minid][j] < lowcost[j]) { lowcost[j] = Graph[minid][j]; } } } cout << sum; } int main() { ios::sync_with_stdio(false); int n, m;//n為頂點的個數,m為邊;
int i, j; cin >> n >> m; for (i = 1; i <= n; i++) { for (j = 1; j <= n; j++) { Graph[i][j] = MaxCost; } } int b, e, cost; for (i = 1; i <= m; i++) { cin >> b >> e >> cost; Graph[b][e] = cost; Graph[e][b] = cost; } prime(n); return 0; }