Dijstra算法输出最短路径

1. 之前我们使用Dijstra算法可以求解出从源点到达其余顶点的最短距离,那么怎么样求解出源点到达v顶点最短距离中所经过的顶点呢?

2. 算法的执行过程如下:

① 其实也很简单,我们只需要在原来使用Dijstra算法求解最短距离的基础上增加上一个pre数组来记录从源点s到顶点v的最短距离中的前一个节点,这样当我们发现可以通过中间顶点u使得从源点s到顶点v的距离更短的时候可以记录从源点到达顶点v的最短路径上的前一个顶点

② 当Dijstra算法结束的时候,那么从源点s到其余顶点的最短距离中所经历的前一个顶点我们就记录下来了,但是我们只是求解出最短路径上每一个顶点的前驱,如何求解完整的路径呢?

pre[4] = 3;
pre[3] = 2;
pre[2] = 1;
pre[1] = 1;

当我们想知道起点v1到达v4的最短路径,就需要先从pre[4]得到v4的前驱节点v3,然后从pre[3]得到v3的前驱节点v2,再从pre[2]得到v2的前驱节点v1,其实这个就是一个递归的过程,不断使用pre的信息寻找前驱

3. 具体的代码如下:

#include<cstdio>
#include<iostream>
using namespace std;
const int maxSize = 1000;
const int INF = 100000000;
int n, m, s, G[maxSize][maxSize];
int d[maxSize];
bool vis[maxSize] = {false};
//pre[v]数组表示从起点到顶点v的最短路径上v的前一个顶点 
int pre[maxSize];
void Dijstra(int s){
	fill(d, d + maxSize, INF);
	d[s] = 0;
	for(int i = 0; i < n; i++){
		int u = -1, min = INF;
		for(int j = 0; j < n; j++){
			if(vis[j] == false && d[j] < min){
				u = j;
				min = d[j];
			}
		}
		if(u == -1) return;
		vis[u] = true;
		for(int v = 0; v < n; v++){
			if(vis[v] == false && G[u][v] != INF && d[u] + G[u][v] < d[v]){
				d[v] = d[u] + G[u][v];
				pre[v] = u;	
			}
		}
	}	
}

//输出源点到顶点v的最短路径
void shortPath(int s, int v){
	if(s == v){
		//相等的时候说明已经找到了第一个节点可以层层返回进行输出 
		cout << s << " ";
		return;
	}
	shortPath(s, pre[v]);
	cout << v << " "; 
}

int main(void){
	int u, v, w;
	cin >> n >> m >> s;
	//初始化的时候将每个顶点的前驱设置为自己
	for(int i = 0; i < n; ++i) pre[i] = i;
	fill(G[0], G[0] + maxSize * maxSize, INF);
	for(int i = 0; i < m; i++){
		cin >> u >> v >> w;
		G[u][v] = w;
	}
	Dijstra(s);
	for(int i = 0; i < n; i++){
		cout << d[i] << " ";
	}
//	cout << endl;
	//使用递归的方法来输出其中的最短路径 
	//输入v顶点 
	cin >> v;
//	cout << s << " " << v << endl;  
	shortPath(s, v);
}

猜你喜欢

转载自blog.csdn.net/qq_39445165/article/details/93207838
今日推荐