实验准备
最小生成树问题,求最小生成树的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;
}