dijkstra算法_想学Dijkstra算法?看这道题就够了!——PAT A1003

0b06add3e0bcd320ff1169baa7cc8754.png

原题链接:

Emergency

题意:

有n个城市,m条路,每一个城市都有一定数量的救援队,给出起始位置,求两点之间的最短路径,输出最短路径的条数及其路程中所遇到的救援队总数,如果最短路径条数大于1,则救援队总数输出几条路径中最大的那一条数量

Sample Input:

5 6 0 2 //n m 起始点 终点
1 2 1 5 3   //每个城市的救援队数量
0 1 1   //城市0与城市1的距离为1
0 2 2
0 3 1
1 2 1
2 4 1
3 4 1

Sample Output:

2 4     //最短路径共两条 最短路径上的最多的救援对数量为4

Dijkstra算法:

本题是关于最短路径的求解问题,针对此类问题,我们可以采用求解最短路径的Dijkstra算法,在解题过程中我们先一起学习Dijkstra算法的流程。

Dijkstra算法核心步骤其实就两条:

  1. 从已知所有路径中选择出最短那条所指向的那个点(未访问过的点),将该点作为已经访问过的点u
  2. 优化 起始点 到 与点u相连的未访问的下个点的距离

再用大白话总结一下上面两条,第一条就是找点,第二条就是找路,找的点自然是从所有路径中发现的最短的路所连接的点,而找的路必然是从刚才的点开始优化的路径。

151c4d88cc3b73158f5e5e91658568a2.gif

上面的动图就很形象地描述了这一过程,注意看这张图,图像中的点还有灰色的状态,也就是我们开始说的点u,这意味这要从该点找路,而红色状态更像是一种确定,即从灰色点找完路后将该点转化为红色点,紧接着就是下个周期的找点操作了(找灰色点)

如果还有点迷,没关系,我们现在看一下相关的技术实现,相信看过技术实现过程+下面的代码,再配合上面的流程就很容易看懂了

首先我们得设立一个判断有无访问过的bool型数组,因为找点需要找未访问过的点,找路则是优化从中介点u(动图中的灰点)与它相连的未访问点之间的边,所以必须设立一个bool型的数组,true表示已经访问过了,false表示未访问。

还有一个关键的数组,即存储起点到各点之间距离的数组d[],初始时,将起点的d[st]设为0,而其余顶点都赋值一个很大的数,而找路过程中优化的也就是这个数组,通过比较这个点vi原来距离起始点st的距离d[vi]与st通过中介点u后的边的距离d[u]+G[u] [vi](表示u与vi之间边的距离)

而其他关于图的存储方式,是邻接表还是邻接矩阵,这都不是本文的重点,因此就不加以赘述

题解:

回归本道题,本题的输入设置都很简单,直接设立相关的变量就好了,在下面代码的注释都写得很清楚了,唯一与上面算法不同的地方是,我们需要设立一个数组用于存储每一个城市的救援队数目,然后在求解过程中我们需要把路过的每个城市的救援队数量也加入数组中,而这难度也不大,我们只需在找路路过程中把这个数组进行累加即可,具体代码如下所示:

#include

本题解说到此结束,后面我还会写关于该算法相关的题目的题解,继续关注哦~

参考:

《算法笔记》 ——胡凡 曾磊

以及承志大佬的

算法数据结构 | 10行实现最短路算法——Dijkstra​mp.weixin.qq.com
13575d40b82ea098f20099f9f54a665f.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值