Dijkstra和SPFA杂想

实际上在没有负边的图上写堆优化的Dijstra和堆优化的SPFA是一样的,所以回去重新考虑了为什么只能用SPFA判断负环。

在不考虑堆优化的时候,Dijstra与SPFA实际上是两种思想。

Dijstra是贪心的思想,和Prime挺像的。Dijstra不只是不能判断负环,它不能用于存在负边的图。所以在一个没有负边的图上,先通过起点的边e找到离起点最近的点v,这个v到起点的最短距离一定是e的边权。走别的点再到v一定没有直接到v优。再用这个最近的的点v更新起点到别的点的距离,标记这个点已经有答案,重复上述过程。如果一旦存在负边,比如a到b距离3,a到c距离5,c到b距离-4,那显然a到b的最短距离是1,而我们在第一步就已经标记了b的最短距离是2,显然Dijstra“出错”了。可能说,那我们不去标记每个点都有答案,但这就成了Bellman-Ford算法。

SPFA从Bellman-Ford而来,是基于迭代思想的。我扫描每个边,用每个边去更新起点到其他点的值。如果更新成功,那么被更新点可能作为中转站减少起点到其他点的距离,因此用被更新点的所有边再更新起点到其他点的距离。为了方便,我们把这些更新成功的点放进队列里,就成了SPFA。在SPFA,我们是不会标记一个点的当前答案就是最终答案的,算法结束条件是队列为空。因此在存在负权的图上,SPFA求最短路是不受影响的。

在存在负边的图上,Dijstra已经无法执行了,那就更不用说在存在负环的图上。那么,SPFA是怎么判断负环的呢?

在无负环的的图上,任意两点的路径都是一条线,不会出现环。这个结论是显然的,任意的环上边权和都是正的,那不如没有。一根线的路径最多经过n个点,有n-1条边,那么显然起点到任意点经过的点数不超过图上总的点数n。那么在SPFA里面每次出现更新的点时,我们就记录起点到这个点的最短路径上经过了几个点。一旦超过n,说明有负环。

猜你喜欢

转载自blog.csdn.net/Luowaterbi/article/details/112693526
今日推荐