13 最短路—Dijkstra算法

本文介绍了Dijkstra算法的基本概念,包括构建邻接矩阵、最短距离上界估计值数组及算法步骤。通过实例展示了算法的执行过程,从所有未选择的点中选取最小估计值点,松弛其出边,直至所有顶点被处理。注意Dijkstra算法不适用于负权边,并且时间复杂度为O(n^2),适合解决单源最短路径问题。
摘要由CSDN通过智能技术生成

 狄克斯特拉算法(Dijkstra)

问题背景与定义

 构建邻接矩阵

 构建最短距离上界的估计值数组

 问题求解过程

1号顶点所有出边进行松弛

2号顶点所有出边进行松弛

 

 4号顶点所有出边进行松弛

3号顶点所有出边进行松弛

5号顶点所有出边进行松弛

 

6号顶点所有出边进行松弛

总结:每次从所有没有进行选择的点中选择“估计值”最小的点,通过该点的所有出边对相连的点进行松弛操作,依次循环,直到所有顶点被选完为止。

主要过程:1、选点    2、出边松弛dis  3、1-2循环过程为n-1次(n为点的个数,最后一个点不再需要进行松弛操作)

问题程序实现

#include <bits/stdc++.h>
using namespace std;

//邻接矩阵方式存储
int f = 9999;
//图的顶点数量与边数
int n = 6, m = 9;

int main() {
	//初始化
	//初始化邻接矩阵
	int e[6][6] = {
		{0, 1, 12, f,  f,  f},
		{f, 0,  9, 3,  f,  f},
		{f, f,  0, f,  5,  f},
		{f, f,  4, 0, 13, 15},
		{f, f,  f, f,  0,  4},
		{f, f,  f, f,  f,  0}
	};
	//初始化dis数组
	int dis[6] = {0, f, f, f, f, f};
	//初始化book数组
	int book[6] = {0};
	int min_index = 0;
	int min_dis = f;
	//实现过程 总的循环过程 寻找n-1个点
	for (int i = 0; i < n - 1; i++) {
		//找点 次数寻找
		min_dis = f;
		for (int j = 0; j < n; j++) {
			if (book[j] == 0 && dis[j] < min_dis) {
				min_dis = dis[j];
				min_index = j;
			}
		}
		//标记点
		book[min_index] = 1;
		//找出边进行松弛操作
		for (int j = 0; j < n; j++) {
			if (e[min_index][j] < f && book[j] == 0) { //出边 且 没有找过该点
				dis[j] = min(dis[j], dis[min_index] + e[min_index][j]); //松弛操作
			}
		}
		//打印松弛过程 
		for (int d = 0; d < n; d++) {
			cout << dis[d] << " ";
		}
		cout<<endl;
	}
	return 0;
}

注意事项:

(1) Dijkstra算法无法解决带有负权边的图(在该算法每步松弛过程后认为找到的最短估计值已经是最短距离,如果后续还有点可以通过负边到达原来的点,使原来的点距离变得更短,那么后面做的工作就是不正确的了)。

(2) Dijkstra算法的时间复杂度为O(n^2),主要解决单源最短距离问题(由源点都任意一点之间的最短距离)。

(3) Dijkstra算法是使用明确边对最短路进行松弛操作,当边的数量远大于点的数量时,该算法可以实现较好的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值