Prim演算法求最小生成樹的c++程式碼實現
阿新 • • 發佈:2019-01-06
Prim演算法是求解最小生成樹的常用方法,它的思想非常簡單,講所有的點集合V分為 已經放入最小生成樹集合的S和未放入的V-S,每次在V-S中選擇一個距離S最近的點放入到S中,直到所有的點都放入S。就是很簡單的貪心策略,不過可以證明是全域性最優,prim演算法對於稠密圖效果比較好,具體步驟可以看點選開啟連結,講解的很清楚。
對於上面的圖,顯然最小生成樹的結果應該是{1,3,6,2,4,5}或者{1,3,6,4,2,5}
#include <iostream> #include<vector> using namespace std; #define MAX_INT 999999 pair<int,int> GetShortestEdge(const vector<vector<int> >& Graph, const vector<bool>& isIncluded )//求當前在MST之外距離MST最近的點的id { int minID = -1; int minDist = MAX_INT; pair<int,int> minEdge; for(int i = 0; i < Graph.size(); i++)//i為MST內的點 { if(!isIncluded[i]) continue;//如果不在MST裡面,則跳過 for(int j = 0; j < Graph.size(); j++) //j為MST外的點 if(!isIncluded[j] && Graph[i][j] < minDist){ //找到不在MST內但是距離MST最近的點 minID = j; minDist = Graph[i][j]; minEdge = make_pair(i,j); } } return minEdge; } vector<pair<int,int> > Prim(const vector<vector<int> >& Graph, vector<bool>& isIncluded){ vector<pair<int,int> > MST; isIncluded[0] = true; //MST.push_back(); for(int i = 1; i < Graph.size(); i++){ pair<int,int> minEdge = GetShortestEdge(Graph, isIncluded); //找到這次要放入的邊i,j MST.push_back(minEdge); //放入 isIncluded[minEdge.second] = true; //將j標記為已經放入 } return MST; } void addEdge( const int& startP, const int& endP, const int& weight ,vector<vector<int> >& Graph) { Graph[startP][endP] = weight; Graph[endP][startP] = weight; } int main() { int vertex_num = 6; vector<vector<int> > Graph(vertex_num, vector<int>(vertex_num, MAX_INT)); addEdge(0,1,6 ,Graph); addEdge(0,2,1 ,Graph); addEdge(0,3,5 ,Graph); addEdge(1,2,5 ,Graph); addEdge(1,4,3 ,Graph); addEdge(2,3,5 ,Graph); addEdge(2,4,6 ,Graph); addEdge(2,5,4,Graph); addEdge(3,5,2,Graph); addEdge(4,5,6,Graph); vector<bool> isIncluded(vertex_num, false); vector<pair<int,int> > MST = Prim(Graph, isIncluded); for(int i = 0; i < MST.size(); i++) //按照放入MST的順序依次輸出 cout << MST[i].first+1 << "->" << MST[i].second+1 << endl; return 0; }
結果如下