摘要:
1,SPFA算法的介绍
2,SPFA算法的解题步骤
3,SPFA算法的负权回路判断
4,SPFA算法的代码实现
5,SPFA算法的几种优化方式(SLF,LLL,堆,栈)
6,SPFA算法和Dijkstra堆优化的区别
1,SPFA算法的介绍
SPFA(Shortest Path Faster Algorithm)最短路径快速算法,是求单源点最短路径的,可以有负权边,但不能有负权回路,实际上它是对 Bellman-Ford 算法使用队列的一种优化。
我们再来回顾下前面讲的Bellman-Ford算法原理,它是每次遍历所有的边然后判断是否能松弛。如下图所示,假设刚开始的时候先计算 <1,3> 这条边,因为顶点 1 的值还没有被更新,起始点到顶点 1 的值是无穷大,用顶点 1 的值去更新顶点 3 是更新不了的。
同理如果顶点 3 的值没有更新,用 <3,4> 这条边计算顶点 4 的值也是更新不了的,所以我们发现一个问题就是在遍历 <x,y> 这条边的时候,如果顶点 x 的值没有改变,那么通过这条边计算 y 的值也不会改变,也就是说使用Bellman-Ford算法会出现大量无效的计算。
解决方式也很简单,就是如果某个顶点的值改变了,我们再来计算它指向的点,如果某个顶点的值没有改变,就不需要计算它指向的点,这个就是 SPFA 算法。
2,SPFA算法的解题步骤
SPFA算法和Bellman-Ford算法类似,只不过SPFA算法并不是每次都盲目的计算所有的边,SPFA算法需要使用一个队列,如果某个顶点的值改变了,它不在队列中,就把它添加到队列中,因为它改变了,它指向的点才有可能改变,所以这里只需要遍历队列中的顶点即可,如下图所示。
我们可以看到顶点 1 和顶点 4 都入队了两次,也就是说在SPFA算法中,一个顶点只要不在队列中,它是可以再次入队的。
它的解题步骤如下:
1,从起始点开始,更新它指向的点,更新之后,把它指向的点添加到队列中。