第四讲图:最短路径两种经典算法学习总结1

2的传送门https://blog.csdn.net/qq_45839708/article/details/104395614

1.迪杰斯特拉(Dijkstra)算法

我们结合图片与代码讲解:
第四讲图:最短路径两种经典算法学习总结1_第1张图片
如上图求最短路径…
有没有人跟我一样第一反应就是用最笨的方法一条路一条路的计算。
很明显这样子是非常浪费时间的,而且运算量对我带说很大。

迪杰斯特拉算法拯救了我(虽然一开始看得非常头大)

迪杰斯特拉算法其核心是:走一步看一步,一步一步的来(31~38行),从而得到最短路径;也实现了源点到所有点的最短路径。

1.const int INF = 1e6;
2.const int N = 1e3;
3.
4.void dijkstra(int n, int mp[N][N], p[N], s[N])	// n代表顶点个数;mp 代表存储着所有点到所有点的邻接矩阵 
5.{												// p 存储着该下标位置的前缀(如p[1] = 0 即为0 -> 1)
6.												// s 为 shortes_path 简写,代表源点到所有点的最短距离 
7.	int i, j, k, min; 							
8.	int judge[N] = {0}; // 判断该下标位置是否已存在最短路径
9.	
10.	for(i = 0; i < n; i++)							
11.	{
12.		s[i] = mp[0][i]; // 初始化最短距离为源点到该点的直接路径长度 
13.		p[i] = 0; // 初始化各点前缀为源点 
14.	}
15.	
16.	s[0] = 0; // 0到0距离为0 
17.	judge[0] = 1; // 0到0已经有最短距离
18.	
19.	for(i = 1; i < n; i++)
20.	{
21.		min = INF;
22.		for(j = 1; j < n; j++)
23.		{
24.			if(!judge[j] && s[j] < min) //寻找此时与源点距离最小的点
25.			{
26.				min = s[j];
27.				k = j;
28.			}
29.		}
30.		judge[k] = 1;  //将此点标记为已拥有最短路径
31.		for(j = 1; j < n; j++)
32.		{								// 此处印证了走一步看一步思想,我们可以以此得到:
33.			if(min + mp[k][j] < s[j]) 	//与此时与源点最短距离点  *相邻的点*  **当前**  的最短路径
34.			{							//(注意是当前的最短距离,不一定是最终的)
35.				s[j] = min + mp[k][j];
36.				p[j] = k; //此时 k 与源点距离最短,则与 k 相邻的点的前缀为 k 
37.			}
38.		}
39.	}
40.}

我们来模拟一下代码:
p 初始化后:{ 0,0,0,0,0,0,0,0,0 };
s 初始化后:{ INF,1,5,INF,INF,INF,INF,INF,INF};-> { 0,1,5,INF,INF,INF,INF,INF,INF };//经过第16行后
judge 初始化后:{ 0,0,0,0,0,0,0,0,0 };-> { 1,0,0,0,0,0,0,0,0 };//经过第17行后

进入第19行
找到第一个 min = s[ 1 ] = 1; k = 1;
如图:
第四讲图:最短路径两种经典算法学习总结1_第2张图片
更新 p , s, judge
p { 0,0,0,0,0,0,0,0,0 };-> { 0,0,111,0,0,0,0 };
s { 0,1,5,INF,INF,INF,INF,INF,INF }; -> { 0,1,486,INF,INF,INF,INF };
judge { 1,0,0,0,0,0,0,0,0 };-> { 1,1,0,0,0,0,0,0,0 };

接下来第二次
如图:
第四讲图:最短路径两种经典算法学习总结1_第3张图片
…持续更新 p , s, judge
最终求得 s 到所有点的最短距离(路径)

你可能感兴趣的:(笔记)