C++实现Dijstra算法(单源路径最短算法)

1. Dijstra算法求解的是图中一个顶点到其余顶点的最短路径

Dijstra算法思想:设有两个顶点集合S和T,集合S中存放的图中已经找到最短路径的顶点,集合T中存放图中剩余顶点,初始状态的时候,集合S中只包含源点v0,然后不断从集合T中选取到顶点v0路径长度最短的顶点v并入到集合S中去,集合S每并入一个新的顶点,都要修改顶点v0到集合T中顶点的最短路径长度值

总结起来我感觉主要有两步:

① 选取源点到其余顶点路径最短的那个顶点

② 每选取一个顶点都要更新从源点到其余顶点的路径,因为每加入一个顶点,有可能使源点到其余顶点通过这个顶点的作用路径变得更短,比如源点0到3的路径一开始为4但是并入1节点之后那么路径为3变短了所以需要更新到3顶点的最短路径

2. 我感觉Dijstra算法与Prim最小生成树的算法很类似,在编程方面上的区别:Prim算法中的d[]数组记录的是其余顶点到当前顶点的最短路径,而Dijstra算法记录的是源点到其余顶点的最短路径,这个区别导致在更新d[]数组的时候的值也是不一样的,我们可以类比这两个算法来进一步理解其中的思想

下面是具体的有向有权的的一个例子:

假如以顶点0作为源点那么首先选取与顶点0相接的顶点,在循环中判断顶点0到相接的顶点的距离是否比之前源点到达这些顶点的路径是更短,可以发现路径是变短了,因为之前是没有路径到达1,3,4顶点的所以需要更新d[]数组中对应的三个顶点,下一次选取源点到达其余顶点中路径最短的,可以发现0到1顶点路径是最短的,所以选择1顶点,重复上面的步骤即可,可以发现1与3顶点相接,那么判断一下1顶点到3顶点的路径是否比之前源点到3的路径更短发现是变短了那么更新,以此类推其余顶点也是一样的道理

测试数据如下:

6 8 0
0 1 1 
0 3 4 
0 4 4 
1 3 2
2 5 1
3 2 2
3 4 3
4 5 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};

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

int main(void){
	int u, v, w;
	cin >> n >> m >> s;
	//初始化二维数组 
	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] << " ";
	}
}

猜你喜欢

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