具体思路参见《算法导论 第三版》
头文件MST.h
#ifndef MST_H_
#define MST_H_
#include<queue>
#include<climits>
using namespace std;
struct Node_Mst{
friend bool operator > (Node_Mst n1,Node_Mst n2){
return n1.key > n2.key;
}
bool vis;//用于记录是否在优先队列里
int key;
int pre;
int num;//记录节点自身的序号
Node_Mst():vis(false),key(INT_MAX),pre(0),num(0){}
Node_Mst(bool vi,int k,int p,int n):vis(vi),key(k),pre(p),num(n){}
};//定义节点
struct Edge_Mst{
int u;
int v;
int w;
Edge_Mst():u(0),v(0),w(0){}
Edge_Mst(int start,int end,int weight = 0):u(start),v(end),w(weight){}
};
class Graph_Mst{
private:
vector<Node_Mst> V;
vector<Edge_Mst> E;
vector<vector<Edge_Mst> >Adj;
public:
Graph_Mst(int v_num,int e_num);
void addEdge(int u,int v,int w = 0);
vector<Node_Mst> MST_Prim(int r);
void MST_Print_Path(vector<Node_Mst> res);
};
#endif /* MST_H_ */
实现MST.cpp
#include"MST.h"
#include<algorithm>
#include<iostream>
using namespace std;
Graph_Mst::Graph_Mst(int v_num,int e_num){
V.resize(v_num);
for(int i = 1;i <= v_num;i++)
V[i-1].num = i;
Adj.resize(v_num);
}
void Graph_Mst::addEdge(int u,int v,int w){
Edge_Mst *te = new Edge_Mst(u,v,w);
E.push_back(*te);
Adj[u-1].push_back(*te);
//无向图(有向图需舍去)
Edge_Mst *te1 = new Edge_Mst(v,u,w);
E.push_back(*te1);
Adj[v-1].push_back(*te1);
}
vector<Node_Mst> Graph_Mst::MST_Prim(int r){
vector<Node_Mst> A;
for(int i = 0;i < V.size();i++){
V[i].vis = false;
V[i].key = INT_MAX;
V[i].pre = 0;
}
V[r-1].key = 0;
priority_queue<Node_Mst,vector<Node_Mst>,greater<Node_Mst> > Q(V.begin(),V.end());
while(!Q.empty()){
int u = Q.top().num;
Q.pop();
V[u-1].vis = true;
A.push_back(V[u-1]);
for(int i = 0;i < Adj[u-1].size();i++){//感觉使用最小堆会好点
int v = Adj[u-1][i].v;
if(!V[v-1].vis && Adj[u-1][i].w < V[v-1].key){
V[v-1].pre = u;
V[v-1].key = Adj[u-1][i].w;
}
while(!Q.empty())//使用优先队列不能随机访问,改变不了队列里面的key值,只能暴力重新构造队列了
Q.pop();
for(int j = 0;j < V.size();j++){
if(!V[j].vis)
Q.push(V[j]);
}
}
}
return A;
}
void Graph_Mst::MST_Print_Path(vector<Node_Mst> res){
if(!res.empty()){
cout << "start Node: " << res[0].num << "\n";
for(int i = 1;i < res.size();i++){
cout << "next Node: " << res[i].num << "It's previous Node: " << res[i].pre << "\n";
}
}
return;
}
测试main.cpp
//测试"MST.h"
#include<iostream>
#include"MST.h"
using namespace std;
int main(){
Graph_Mst G(9,15);
G.addEdge(1,2,4);
G.addEdge(1,8,8);
G.addEdge(2,3,8);
G.addEdge(2,8,11);
G.addEdge(3,4,7);
G.addEdge(3,6,4);
G.addEdge(3,9,2);
G.addEdge(4,5,9);
G.addEdge(4,6,14);
G.addEdge(5,6,10);
G.addEdge(6,7,2);
G.addEdge(7,9,6);
G.addEdge(7,8,1);
G.addEdge(8,9,7);
vector<Node_Mst> res = G.MST_Prim(1);
G.MST_Print_Path(res);
return 0;
}
其他算法实现见GitHub