【C++】Prim算法代码(注释详细,已调试)

#include<iostream>
#include<string>
#include<vector>
#include<math.h>

using namespace std;

//设为最大值的一半向下取整的值,使得两个最大值相加不会溢出
#define HALF_MAX floor(DBL_MAX/2)

void Prim(vector<bool>& visit, vector<double>& lowcost,
	vector<int>& closest, vector<vector<double>>& c, int n) {
	//设置vector容器大小
	visit.resize(n + 1);
	lowcost.resize(n + 1);
	closest.resize(n + 1);

	//初始化,S中只有第一个点
	for (int i = 1; i <= n; ++i) {
		//最短距离设为其它点到第一个点的距离(不相邻则为无穷大)
		lowcost[i] = c[1][i];
		closest[i] = 1;//初始情况下所有点的临界点均为第一个点
		visit[i] = false;//所有点均未访问过
	}
	visit[1] = true;//访问第一个点

	//访问除第1个点外的其它点,访问顺序跟序号无关
	//访问第1个点的处理在初始化中已完成
	for (int i = 2; i <= n; ++i) {
		int j = 1;

		//在未访问的点中,找出到达S距离最短的点
		for (int k = 1; k <= n; ++k) {
			//若k未被访问,且到达S的距离小于j,更新
			if ((!visit[k]) && (lowcost[k] < lowcost[j]))
				j = k;
		}
		visit[j] = true;//将j添加到S中

		//更新添加j之后的lowcost[]和closest[]的值
		for (int k = 1; k <= n; ++k) {
			//若k未被访问,且 j到k的距离 小于 添加j之前k到S的距离,更新
			if ((!visit[k]) && (c[j][k] < lowcost[k])) {
				lowcost[k] = c[j][k];//更新最短距离
				closest[k] = j;//更新k在S中的最近邻点
			}
		}
	}
}

int main(void) {
	//所有序号从1开始
	int n = 4;//基站个数,在使用Prim函数之前已经传入数据
	vector<vector<double>> c;//矩阵,在使用Prim函数之前已经传入数据
							 //每个点到达自己的距离设为无穷大(或者任意大于最大距离的值)
							 //否则会影响Prim()中访问点的选取
							 //每个点到达不相邻点的距离设为无穷大
	vector<double> lowcost;//记录S外的点到S的最短距离
	vector<int> closest;//记录S外的点在S中的距离最短的点
	vector<bool> visit;//标记节点是否被访问
	vector<int> ID;//基站ID

	/*调试数据*/
	double a[4][4] = { {HALF_MAX,2,HALF_MAX,HALF_MAX},{2,HALF_MAX,2,4},
					{HALF_MAX,2,HALF_MAX,3},{HALF_MAX,4,3,HALF_MAX} };
	c.resize(n + 1, (vector<double>)(n + 1));

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= n; ++j) {
			c[i][j] = a[i-1][j-1];
		}
	}

	Prim(visit, lowcost, closest, c, n);

	int lowest_cost = 0;//最小生成树的代价

	//由于S的初始化点(第一个点)到达自己的距离为无穷大,去掉这个数据,j从2开始
	for (int j = 2; j < lowcost.size(); ++j) {
		lowest_cost += lowcost[j];
	}

	cout << "最小生成树的代价为:" << lowest_cost << endl;
	cout << "最小生成树的边为:" << endl;

	//同理,去掉第一个点的数据,n个点,n-1条边
	for (int j = 2; j <= n; ++j) {
		cout << "\tV" << j << " ---- V" << closest[j] << endl;
	}

	return 0;
}

调试结果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章