Prim最小生成树算法C++实现

本文深入探讨了Prim算法,一种用于解决最小生成树问题的经典算法。通过详细解释算法原理,结合C++代码实现,展示了如何从一个顶点出发,逐步构建最小生成树,直至覆盖所有顶点。文章还介绍了使用优先队列优化算法过程,提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

时间:o(n2) 空间:o(n)

集合避圈法,解决连通各个单位,费用最少的问题。
选取一点加入S集合中,一次选取V-S离S集合最近的点,加入S中,知道V-S为空集,最小生成树完成。
使用优先队列优化

#include<iostream>
#include<queue>
using namespace std;
const int maxnum = 100;
const int inf = 0x3f3f3f3f;
typedef struct graph {
	int vexs[maxnum][maxnum];
	int vexnums;
	int edgenums;
}G; //带权邻接矩阵
typedef struct edge {
	int u;
	int v;
	int w;
	edge(int ui, int vi, int wi)
	{
		u = ui;
		v = vi;
		w = wi;
	}
	edge() 
	{

	}
	//运算符重载
	friend bool operator >(const edge e1,const edge e2)
	{
		return e1.w > e2.w;
	}
}edge;
G g;
bool s[maxnum];
//构建邻接矩阵
void creategraph() {
	cout << "输入顶点数量和边数量:" << endl;
	cin >> g.vexnums >> g.edgenums;
	cout << "输入对应的边关系:" << endl;
	for (int i = 1; i <= g.vexnums; i++)
	{
		for (int j = 1; j <= g.vexnums; j++)
		{
			g.vexs[i][j] = inf;
		}
	}
	for (int i = 0; i < g.edgenums; i++)
	{
		int a, b, w;
		cin >> a >> b >> w;
		g.vexs[a][b] = w;
		g.vexs[b][a] = w;
	}
}
void prim(int u) 
{
	int wpl = 0;
	s[u] = true;							//将u顶点加入s集合中
	priority_queue<edge,vector<edge>,greater<edge> > queue;				//边队列
	edge* path = new edge[g.vexnums - 1];		//最小生成树结果
	int k = 0;
	//将u顶点的邻接边都加入队列中
	for (int i = 1; i <= g.vexnums; i++)
	{
		queue.push(edge(u, i, g.vexs[u][i]));
	}
	for (int i = 1;; i++)
	{
		//求出v-s内最近顶点
		edge e = queue.top();
		int t = e.v;
		queue.pop();
		cout << e.u << "-->" << e.v << "-->" << e.w <<"-->"<<s[t]<<endl;
		if (e.w==inf||k==g.vexnums-1) break;
		if (s[t]) continue;
		s[t] = true;						//把顶点加入S中
		path[k++] = e;
		wpl += e.w;
		//更新queue将改变的边重新加入队列中
		for (int i = 1; i <= g.vexnums; i++)
		{
			if (!s[i])
			{
				queue.push(edge(t, i, g.vexs[t][i]));		//t->i
			}
		}
	}
	cout << "WPL:" << wpl << endl;	
	cout << "最小生成树路径为:" << endl;
	for (int i = 0; i < k; i++)
	{
		cout << "<" << path[i].u << "," << path[i].v << "> ";
	}
	cout << endl;
}
int main() 
{
	creategraph();
	int u;
	cin >> u;
	prim(u);
	return 0;
}

测试数据
7 12
1 2 23
1 6 28
1 7 36
2 3 20
2 7 1
3 7 4
3 4 15
4 7 9
4 5 3
5 7 16
5 6 17
6 7 25
1
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JustEasyCode

谢谢您

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值