__3.7.1 最短路径—迪杰斯特拉算法

#include "pch.h"
#include "__0 Basic_operation.h"
#include <iostream>
#include <vector>
#include <stack>

typedef vector<int> PathArc;			//用于存储最短路径下标的数组
typedef vector<int> ShortPathTable;		//用于存储到各点最短路径的的权值和


/*  Dijkstra算法	*/

/*求无向网G的顶点V0到其余顶点V的最短路径P[V]及带权长度D[V]*/
/*P[V]的值为前驱顶点的下标,D[V]表示V0到V的最短路径长度和*/
void ShortestPath_Dijkstra(const MGraph& G, int V0, PathArc& P, ShortPathTable& D)
{
	P.resize(G.numVertexes);	//设置数组大小
	D.resize(G.numVertexes);	
	//用于记录已经求得最短路径的顶点,final[w] = 1表示求得顶点Vv0至Vw的最短路径
	vector<int> final(G.numVertexes, 0);	//顶点全部初始化为未知最短路径状态

	/* 初始化数据 */
	for (int v = 0; v < G.numVertexes; ++v) {
		D[v] = G.arcs[V0][v];	//将与V0点有连线的顶点加上权值
		P[v] = V0;				//初始化路径数组P为 Vv0,表示所有点都以V0为起点
	}
	P[V0] = -1;		//V0至V0不需要路径,前驱设置为-1
	D[V0] = 0;		//V0至V0权值为0
	final[V0] = 1;	//V0已经在最短路径中

	/*开始主循环,每次求得V0至某个顶点V的最短路径*/
	for (int v = 0; v < G.numVertexes; ++v) {
		int min = myINFINITY;
		int k = 0;
		/*寻找离V0最近的顶点*/
		for (int w = 0; w < G.numVertexes; ++w) {
			if (!final[w] && D[w] < min) {
				k = w;
				min = D[w];		//w顶点离V0更近
			}
		}
		final[k] = 1;		//将目前找到的最近的顶点置为1
		/*修正当前最短路径及距离*/
		for (int w = 0; w < G.numVertexes; ++w) {
			/*如果经过顶点Vk从Vv0到顶点Vw的路径比原有Vv0到Vw的路径短的话*/
			if (!final[w] && (min + G.arcs[k][w] < D[w])) {
				/*说明找到了从Vv0到Vw更短的路径,修改D[w]和P[w]*/
				D[w] = min + G.arcs[k][w];		//修改当前路径长度
				P[w] = k;		//将Vw的前驱改为Vk
			}
		}
	}
}

/*打印结果*/
void ShowResult(const PathArc& P, const ShortPathTable& D, int numVertexes, int V0) {
	for (int w = 0; w < numVertexes; ++w) {
		if (w == V0)	//终点与源点相等,跳过此次循环
			continue;
		std::stack<int> s;
		int v = w;
		while (v != V0) {	//将路径节点压入栈中
			s.push(v);
			v = P[v];		//获得下一个路径顶点下标
		}

		std::cout << " V" << V0 << " -- V" << w << "  weight:" << right << setw(2) << D[w];
		std::cout << "  path: " << V0;		//打印源点
		while (!s.empty()) {
			std::cout << " -> " << s.top();	//打印路径顶点
			s.pop();
		}
		std::cout << std::endl;
	}
}


int main() {
	/*  P260 无向网               0  1  2  3  4  5  6  7  8  */
	vector<vector<EdgeType>> vv{ {0, 1, 5, N, N, N, N, N, N},
								 {1, 0, 3, 7, 5, N, N, N, N},
								 {5, 3, 0, N, 1, 7, N, N, N},
								 {N, 7, N, 0, 2, N, 3, N, N},
								 {N, 5, 1, 2, 0, 3, 6, 9, N},
								 {N, N, 7, N, 3, 0, N, 5, N},
								 {N, N, N, 3, 6, N, 0, 2, 7},
								 {N, N, N, N, 9, 5, 2, 0, 4},
								 {N, N, N, N, N, N, 7, 4, 0} };
	MGraph G;
	CreateMGraphByArray(G, vv, 0);		//传入 0 表示无向图
	ShowMGraph(G);

	PathArc P;
	ShortPathTable D;
	int V0;
	std::cout << "\n请输入路径源点:(0 - 8) ";
	std::cin >> V0;
	ShortestPath_Dijkstra(G, V0, P, D);	//传入路径源点 V0
	std::cout << "\n迪杰斯特拉算法求得的最短路径: \n";
	ShowResult(P, D, G.numVertexes, V0); //传入顶点个数和源点V0

	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40843865/article/details/89225076