Dijkstra最短路径算法
先重申游戏设定(和之前一致,方便你对照):
- 目标:从你座位(起点)到小明座位(终点),走最少步数(最短路径)。
- 教室地图(关键改1处:加一条“能直接到终点的路”):
1. 你→小红(1步);2. 你→小刚(1步);3. 小红→小明(1步);4. 小刚→小明(2步);5. 你→小明(3步)(新增的“直接到终点的路”,但步数多)。
- 工具:步数本(记最少步数)、小红旗(插在“步数确定不变”的座位上)。
关键场景:当你“第一次看到终点”时,怎么处理其他路?
咱们从游戏第三步开始,重点看“发现终点后,还要做什么”——
第一步:游戏开局(和之前一样)
- 步数本初始:你(0步,红旗)、小红(?)、小刚(?)、小明(?)。
- 从你出发,更新步数本:小红(1步)、小刚(1步)、小明(3步,因为你能直接走到他,要3步)。
- 插第二面红旗:选小红(1步,和小刚一样,先选小红)。
第二步:从“小红(红旗)”出发,第一次找到“到终点的近路”
1. 小红能到小明,只要1步。那“你→小红→小明”的总步数是:1(你到小红)+1(小红到小明)= 2步。
2. 对比步数本:之前你直接到小明要3步,现在2步更近!所以把步数本上“小明”的3步,改成2步。
此时步数本:你(0,旗)、小红(1,旗)、小刚(1)、小明(2)。
3. 重点来了:现在你已经知道“到小明只要2步”,但不能直接结束!还要处理“小刚”这条路——因为你还没看从小刚出发,能不能找到更近的路(虽然大概率不能,但必须确认,才不算漏)。
第三步:处理“没插旗的小刚”,确认其他路是否更近
1. 插第三面红旗:没插旗的座位里,小刚(1步)比小明(2步)近,所以先给小刚插红旗。
2. 从小刚出发,看能到谁:小刚能到小明,要2步。那“你→小刚→小明”的总步数是:1(你到小刚)+2(小刚到小明)= 3步。
3. 对比步数本:小明当前是2步,3步比2步远,所以步数本上“小明”的步数不变(还是2步)。
这一步的作用是:确认了“小刚这条路”到终点更远,所以不用改,咱们之前找到的2步才是真的最短。
第四步:最后给“小明”插红旗,游戏结束
1. 现在没插旗的只有小明(2步),给他插红旗。
2. 插旗后,“小明的步数(2步)”就100%确定了——因为所有能到小明的路(你直接去、小红去、小刚去)都检查过了,没有比2步更近的。
3. 最终最短路径:你→小红→小明(2步)。
总结:“一条路先到终点,怎么看其他路”的核心逻辑
就像你找小明时,虽然先发现“走小红的路只要2步到终点”,但必须再去看“小刚的路”要几步——
不是怀疑“小红的路”不对,而是要确认“有没有其他路比它更短”。只有把所有能到终点的路都算一遍,对比出最小的那个数,才能确定“这就是最短路径”,不会漏掉更优的选择。
比如你妈妈给你10块钱买零食,你先看到A店薯片卖8块,不能直接买,得再看看B店是不是卖7块——只有都看了,才能确定在哪家买更省钱,和算法的道理一模一样!