这是一个非常容易理解,非常简单的算法。
Prim算法是一种用于求解最小生成树的经典算法之一,它通过逐步选择与当前生成树相邻的具有最小权值的边来构建最小生成树。
Prim算法步骤:
-
初始化:选择任意一个顶点作为起始点,将其加入最小生成树中,并将其相邻的边加入候选边集合。
-
重复以下步骤直到所有顶点都被加入最小生成树:
- 从候选边集合中选择权值最小的边,将其加入最小生成树,并将其连接的顶点加入最小生成树的顶点集合。
- 更新候选边集合,将新加入的顶点的所有相邻边中未在最小生成树中的边加入候选边集合。
Prim(G, start):
初始化空集合MST,空集合visited
将start加入visited
初始化优先队列PQ,加入与start相连的边当visited中的顶点数量不等于G中的所有顶点数量时: 从PQ中取出权值最小的边edge 如果edge.to不在visited中: 将edge加入MST 将edge.to加入visited 对于edge.to相连的每条边: 如果边的另一端点不在visited中: 将边加入PQ 返回MST
cpp
#include <iostream>
#include <vector>
#include <queue>
#include <utility>
using namespace std;
#define INF 0x3f3f3f3f
typedef pair<int, int> pii;
void primMST(vector<vector<pii>>& graph, int start) {
int V = graph.size();
vector<int> key(V, INF);//快速赋值方法
vector<bool> inMST(V, false);
vector<int> parent(V, -1);
priority_queue<pii, vector<pii>, greater<pii>> pq;
pq.push(make_pair(0, start));
key[start] = 0;
while (!pq.empty()) {
int u = pq.top().second;
pq.pop();
inMST[u] = true;
for (auto& neighbor : graph[u]) {
int v = neighbor.first;
int weight = neighbor.second;
if (!inMST[v] && weight < key[v]) {
key[v] = weight;
pq.push(make_pair(key[v], v));
parent[v] = u;
}
}
}
// Print the MST
cout << "Edge \tWeight\n";
for (int i = 1; i < V; i++) {
cout << parent[i] << " - " << i << "\t" << graph[i][parent[i]].second << "\n";
}
}