📅  最后修改于: 2023-12-03 15:03:52.079000             🧑  作者: Mango
Prim's算法是一种用于解决最小生成树问题的贪心算法,它通过选择当前集合到未访问节点的最小边来构建最小生成树。在STL中,我们可以使用priority_queue数据结构来辅助实现Prim's算法。
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
// 定义边的结构
struct Edge {
int src, dest, weight;
};
// 定义比较函数用于优先队列的排序
struct Compare {
bool operator()(Edge const& e1, Edge const& e2) {
// 边的权重越小,优先级越高
return e1.weight > e2.weight;
}
};
void prim(vector<vector<pair<int, int>>>& graph, int start) {
int vertices = graph.size();
// 存储最小生成树的边
vector<Edge> mst;
// 标记顶点是否被访问
vector<bool> visited(vertices, false);
// 定义优先队列(最小堆)
priority_queue<Edge, vector<Edge>, Compare> pq;
// 将起始节点及其邻居边加入优先队列
for (auto neighbor : graph[start]) {
int dest = neighbor.first;
int weight = neighbor.second;
pq.push({start, dest, weight});
}
visited[start] = true;
while (!pq.empty()) {
Edge e = pq.top();
pq.pop();
int dest = e.dest;
// 如果相邻顶点已经被访问,跳过当前边
if (visited[dest])
continue;
// 将边加入最小生成树
mst.push_back(e);
visited[dest] = true;
// 将相邻顶点及边加入优先队列
for (auto neighbor : graph[dest]) {
int nextDest = neighbor.first;
int weight = neighbor.second;
pq.push({dest, nextDest, weight});
}
}
// 打印最小生成树
cout << "Minimum Spanning Tree:" << endl;
for (auto edge : mst) {
cout << edge.src << " -> " << edge.dest << " : " << edge.weight << endl;
}
}
int main() {
int vertices, edges;
cout << "Enter the number of vertices: ";
cin >> vertices;
cout << "Enter the number of edges: ";
cin >> edges;
vector<vector<pair<int, int>>> graph(vertices);
cout << "Enter the edges (src, dest, weight):" << endl;
for (int i = 0; i < edges; i++) {
int src, dest, weight;
cin >> src >> dest >> weight;
graph[src].push_back({dest, weight});
graph[dest].push_back({src, weight});
}
int start;
cout << "Enter the start vertex: ";
cin >> start;
prim(graph, start);
return 0;
}
以上代码是一个使用Prim's算法和STL中的priority_queue
实现的最小生成树的例子。输入顶点、边以及边的权重,然后输入开始的顶点,并输出最小生成树的结果。
总之,Prim's算法是解决最小生成树问题的常用贪心算法,而STL中的优先队列(priority_queue
)是实现Prim's算法的有效工具。优先队列通过调整边的优先级来确保选择权重最小的边,从而构建一个最小生成树。