油管铺设 离散数学 合工大 prim算法

实验准备
最小生成树问题,求最小生成树的Prim算法
实验目的
运用最小生成树思想和求最小生成树程序解决实际问题
实验过程
八口海上油井相互间距离如下表,其中1号井离海岸最近,为5km。问从海岸经1号井铺设油管把各井连接起来,怎样连油管长度最短(为便于检修,油管只准在油井处分叉)?

从~到 2 3 4 5 6 7 8
1 1.3 2.1 0.9 0.7 1.8 2.0 1.8
2 0.9 1.8 1.2 2.8 2.3 1.1
3 2.6 1.7 2.5 1.9 1.0
4 0.7 1.6 1.5 0.9
5 0.9 1.1 0.8
6 0.6 1.0
7 0.5

当初网上搜了一下发现没有prim算法的c++实现代码,有也写的特别烂。于是自己动手,丰衣足食,同时造福各位同学。


请不要用上古版本的c++运行代码,推荐使用vs2019

#include<iostream>
using namespace std;



class MGraph {
public:
	int vex[8] = { 1,2,3,4,5,6,7,8 };
	double edge[8][8] = {
		    0.0, 1.3, 2.1, 0.9, 0.7, 1.8, 2.0, 1.8,
			1.3, 0.0, 0.9, 1.8, 1.2, 2.8, 2.3, 1.1,
			2.1, 0.9, 0.0, 2.6, 1.7, 2.5, 1.9, 1.0,
			0.9, 1.8, 2.6, 0.0, 0.7, 1.6, 1.5, 0.9,
			0.7, 1.2, 1.7, 0.7, 0.0, 0.9, 1.1, 0.8,
			1.8, 2.8, 2.5, 1.6, 0.9, 0.0, 0.6, 1.0,
			2.0, 2.3, 1.9, 1.5, 1.1, 0.6, 0.0, 0.5,
			1.8, 1.1, 1.0, 0.9, 0.8, 1.0, 0.5, 0.0
	};
	static const int vexnum = 8;
};
void Prim(MGraph g, int v0, int& sum);


/*
v0是初始化的起始点
v是另一个顶点
sum是记录所有走过的路径权值之和
lowcost是记录从当前所有已加入的点中,到未加入的点中的最短距离
min是记录一个临时比较的值。它用来辅助比较出最小的最短距离
vset是顶点集,标为0代表还没有被算过(走过),标为1代表已经被算过(走过)了。
*/

void Prim(MGraph g, int v0, double& sum) {
	int  vset[8], v;
	double lowcost[8], min;
	int i, j, k;
	v = v0;
	cout << "起始点:" << g.vex[v0] << endl <<"下面按顺序依次通过:"  << endl;
	//现在把最小权值记录为从初始点出发的边的权值,并把所有点标记为0,代表还没算过
	for (i = 0; i < g.vexnum; ++i) {
		lowcost[i] = g.edge[v0][i];
		vset[i] = 0;
	}
	vset[v0] = 1;//初始点标为1,表示算过了
	sum = 5;
	for (i = 0; i < g.vexnum - 1; ++i) {
		min = 1000;
		//下面从当前生成树到其余顶点最短边中权值最小的一条
		for (j = 0; j < g.vexnum; ++j) {
			if (vset[j] == 0 && lowcost[j] < min) {
				min = lowcost[j];
				k = j;
			}
		}
		vset[k] = 1;//找到后记为1
		v = k;
		cout << "通过点" << g.vex[v] << "   当前点权值为:" << min << endl;
		sum += min;
		//下面是 以刚加入的顶点v为中介点,更新所有最短边的权值
		for (j = 0; j < g.vexnum; ++j) {
			if (vset[j] == 0 && g.edge[v][j] < lowcost[j]) {
				lowcost[j] = g.edge[v][j];
			}
		}	
	}
	cout << "所有路径总和为:" << sum << "(已经加上了从海岸到1的长度5km)" << endl;
}

int main(void) {
	MGraph g;
	/*g.edge = {
		0.0,	1.3,	2.1,	0.9,	0.7,	1.8,	2.0,	1.8,
		1.3,	0.0,	0.9,	1.8,	1.2,	2.8,	2.3,	1.1,
		2.1,	0.9,	0.0,	2.6,	1.7,	2.5,	1.9,	1.0,
		0.9,	1.8,	2.6,	0.0,	0.7,	1.6,	1.5,	0.9,
		0.7,	1.2,	1.7,	0.7,	0.0,	0.9,	1.1,	0.8,
		1.8,	2.8,	2.5,	1.6,	0.9,	0.0,	0.6,	1.0,
		2.0,	2.3,	1.9,	1.5,	1.1,	0.6,	0.0,	0.5,
		1.8,	1.1,	1.0,	0.9,	0.8,	1.0,	0.5,	0.0
	};
	g.vex = { 1,2,3,4,5,6,7,8 };*/
	double sum = 0; 
	int v0 = 0;
	Prim(g,v0,sum);
	
	return 0;
}

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值