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

39 篇文章 2 订阅

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

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

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

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

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

2. 我感觉Dijkstra算法与Prim最小生成树的算法很类似,在编程方面上的区别:Prim算法中的d[]数组记录的是其余顶点到当前顶点的最短路径,而Dijkstra算法记录的是源点到其余顶点的最短路径,这个区别导致在更新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 Dijkstra(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;
	}
	Dijkstra(s);
	for(int i = 0; i < n; i++){
		cout << d[i] << " ";
	}
}

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值