【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;
}

調試結果

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