十七、最短路径问题(SPFA)

来源:互联网 发布:淘宝怎么添加客服号 编辑:程序博客网 时间:2024/05/23 22:45

SPFA算法:

SPFA算法全称是Shortest Path Faster Algorithm。
Dijkstra不能解决负权边,Bellman-Ford算法效率底,可使用SPFA算法。
与Dijkstra算法和Bellman-Ford算法一样,用数组d记录每个节点的最短路长估计,并且用邻接表来存储图G。
采用动态逼近的方法:设立一个先进先出的队列Q,用来保存待优化的节点,优化时每次取出队首节点u,并且用u点当前的最短路长估计对u点出边所指向的节点v进行松弛操作,如果v点的最短路长估计有所调整,且v点不在当前的队列中,就将v点放入Q队的队尾。这样不断从队列Q中取出节点来进行松弛操作,直至Q队列空为止。

Proc SPFA(G,w,s);
{ initiallze_single_source(G,s);
  队列Q初始化为空; 源点s入队列Q;
  while Q队列非空 do
  { 从Q中取出队首节点u;
    for each v∈u相邻的节点集 do
    { tmp:=d[v];relax(u,v,w);
      if (d[v]<tmp) and (v不在Q内) then v进入Q队尾;
     }    
  }
}


SPFA算法的期望时间复杂度为O(E)。

思考:怎么判断负权回路?


SPFA算法与Bellman-Ford算法比较:

同:两者都属于标号修正的范畴,计算过程都是迭代式的,最短路长估计值都是临时的,都采用了不断逼近最优解的贪心策略,只在最后一步才确定想要的结果。

差异:在Bellman-Ford算法中,要是某个点的最短路长估计值被更新了,那么就必须对所有边的尾做一次松弛操作;在SPFA算法中,某个点的最短路径估计值被更新,仅需要对该点出边的端点做一次松弛操作。


习题:

1.codevs1557

2.http://blog.csdn.net/boyxiejunboy/article/details/46909971(想越狱的小衫)

3.冰原探险(难)

1 0
原创粉丝点击