1.簡介
Prim算法是圖論中的一種算法,可在帶權連通圖里搜索產生最小生成樹。
該算法於1930年由捷克數學家沃伊捷赫·亞爾尼克(Vojtěch Jarník)發現;並在1957年由美國計算機科學家羅伯特·普里姆(Robert C. Prim)獨立發現;1959年,艾茲格·迪科斯徹再次發現了該算法。
Prim算法從任意一個頂點開始,每次選擇一個與當前頂點集最近的一個頂點,並將兩頂點之間的邊加入到樹中,在找當前最近頂點時使用到了貪心算法。
預備知識(了解的跳過):
2.實例
先給出一個這樣的鄰接矩陣,找最小生成樹吧:
把鄰接矩陣可以翻譯成這樣的無向圖:
過程:
Prim算法是基於節點做優先考慮的,以某一節點開始作為根節點,不斷搜索距離的權值最小的節點,然后加入到生成樹中。
3.代碼
#include<bits/stdc++.h> #define INF 99999 using namespace std; const int N = 6; bool visit[N]; int dist[N] = { 0, }; int graph[N][N] = { {0,6,1,5,INF,INF}, //INF代表兩點之間不可達 {6,0,5,INF,3,INF}, {1,5,0,5,6,4}, {5,INF,5,0,INF,2}, {INF,3,6,INF,0,6}, {INF,INF,4,2,6,0} }; int prim(int cur){ int index = cur; int sum = 0,i = 0,j = 0; cout << index << " "; memset(visit,false, sizeof(visit)); visit[cur] = true; for(i = 0; i < N; i++) dist[i] = graph[cur][i];//初始化,每個與a鄰接的點的距離存入dist for(i = 1; i < N; i++){ int minor = INF; for(j = 0; j < N; j++){ if(!visit[j] && dist[j] < minor){ //找到未訪問的點中,距離當前最小生成樹距離最小的點 minor = dist[j]; index = j; } } visit[index] = true; cout << index << " "; sum += minor; for(j = 0; j < N; j++){ if(!visit[j] && dist[j]>graph[index][j]) //執行更新,如果點距離當前點的距離更近,就更新dist { dist[j] = graph[index][j]; } } } cout<<endl; return sum; //返回最小生成樹的總路徑值 } int main(){ cout << prim(0) << endl;//從頂點a開始 return 0; }