Prim算法是一种用于解决最小生成树(Minimum Spanning Tree,简称MST)问题的贪心算法。最小生成树是一个无向图中的一棵包含所有节点的树,使得树的所有边的权重之和最小。
Prim算法的主要目标是选择图中的边,构建一棵最小生成树。其基本思想是从一个初始节点开始,每次选择与当前生成树相邻的、具有最小权重的边,直到所有节点都被包含在最小生成树中。
Prim算法的步骤如下:
- 初始化一个空的最小生成树。
- 选择一个起始节点,将其加入最小生成树中。
- 在所有与最小生成树中的节点相邻的边中,选择权重最小的边,并将与这条边相邻的节点加入最小生成树。
- 重复步骤3,直到所有节点都包含在最小生成树中。
Prim算法的应用场景包括网络设计、电缆布线、电路设计等需要在节点之间建立连接的问题。最小生成树能够以最小的总成本连接所有节点,从而节省资源和成本。
总的来说,Prim算法的主要作用是找到一个连接所有节点的最小权重的树,以满足特定的约束条件。
代码:
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
const int INF = INT_MAX;
// 定义图的邻接矩阵表示
typedef vector<vector<int>> Graph;
// 找到当前最小生成树中与集合S相邻的最小边的顶点
int findMinVertex(const vector<int>& key, const vector<bool>& inMST) {
int minVertex = -1;
int minKey = INF;
for (size_t v = 0; v < key.size(); ++v) {
if (!inMST[v] && key[v] < minKey) {
minKey = key[v];
minVertex = v;
}
}
return minVertex;
}
// 打印最小生成树的边
void printMST(const vector<int>& parent, const Graph& graph) {
cout << "Edge Weight\n";
for (size_t i = 1; i < parent.size(); ++i) {
cout << parent[i] << " - " << i << " " << graph[i][parent[i]] << "\n";
}
}
void prim(const Graph& graph) {
int n = graph.size();
// 存储最小生成树中每个节点的父节点
vector<int> parent(n, -1);
// 存储每个节点与最小生成树的最小权重
vector<int> key(n, INF);
// 存储节点是否在最小生成树中的标记
vector<bool> inMST(n, false);
// 选择初始节点
key[0] = 0;
// 构建最小生成树
for (int count = 0; count < n - 1; ++count) {
// 从尚未包含在最小生成树中的节点中找到最小权重的节点
int u = findMinVertex(key, inMST);
// 将找到的节点标记为已包含
inMST[u] = true;
// 更新与新节点相邻的节点的最小权重和父节点信息
for (int v = 0; v < n; ++v) {
if (graph[u][v] != 0 && !inMST[v] && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}
// 打印最小生成树的边
printMST(parent, graph);
}
int main() {
// 示例图的邻接矩阵表示
Graph graph = {
{0, 2, 0, 6, 0},
{2, 0, 3, 8, 5},
{0, 3, 0, 0, 7},
{6, 8, 0, 0, 9},
{0, 5, 7, 9, 0}
};
// 执行Prim算法
prim(graph);
return 0;
}
findMinVertex
函数用于找到当前最小生成树中与集合S相邻的最小边的顶点。printMST
函数用于打印最小生成树的边。prim
函数实现Prim算法,构建最小生成树。- 在
main
函数中,我们定义了一个示例图的邻接矩阵,并调用prim
函数执行Prim算法。
在Prim算法中,我们使用三个数组来维护算法过程中的信息:
parent
数组用于存储每个节点的父节点。key
数组用于存储每个节点与最小生成树的最小权重。inMST
数组用于标记每个节点是否已经包含在最小生成树中。
最终,通过 printMST
函数打印最小生成树的边。这个示例代码的图是一个带权重的无向图,Prim算法通过贪心的策略逐步构建最小生成树。