关于求最短路径:

求最短路径的算法有许多种,除了排序外,恐怕是OI界中解决同一类问题算法最多的了。最熟悉的无疑是Dijkstra(不能求又负权边的图),接着是Bellman-Ford,它们都可以求出由一个源点向其他各点的最短路径;如果我们想要求出每一对顶点之间的最短路径的话,还可以用Floyd-Warshall。

关于松弛:

松弛操作的原理是著名的定理:“三角形两边之和大于第三边”,在信息学中我们叫它三角不等式。所谓对i,j进行松弛,就是判定是否d[j]>d[i]+w[i,j],如果该式成立则将d[j]减小到d[i]+w[i,j],否则不动。

SPFA简介:

求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm,该算法是西南交通大学段凡丁于1994年发表的(一看到这点就觉得西南交大碉堡了)。它可以在O(kE)的时间复杂度内求出源点到其他所有点的最短路径,其中k为所有顶点进队的平均次数,可以证明k一般小于等于2,可以处理负边,但无法处理带负环的图(负环和负边不是一个概念)。SPFA的实现甚至比Dijkstra或者Bellman_Ford还要简单。

SPFA算法过程:

我们记源点为S,由源点到达点i的“当前最短路径”为D[i],开始时将所有D[i]初始化为无穷大,D[S]则初始化为0。算法所要做的,就是在运行过程中,不断尝试减小D[]数组的元素,最终将其中每一个元素减小到实际的最短路径。

过程中,我们要维护一个队列,开始时将源点置于队首,然后反复进行这样的操作,直到队列为空:

(1)从队首取出一个结点u,扫描所有由u结点可以一步到达的结点,具体的扫描过程,随存储方式的不同而不同;

(2)一旦发现有这样一个结点,记为v,满足D[v] > D[u] + w(u, v),则将D[v]的值减小,减小到和D[u] + w(u, v)相等。其中,w(u, v)为图中的边u-v的长度,由于u-v必相邻,所以这个长度一定已知(不然我们得到的也不叫一个完整的图);这种操作叫做松弛。

(3)上一步中,我们认为我们“改进了”结点v的最短路径,结点v的当前路径长度D[v]相比于以前减小了一些,于是,与v相连的一些结点的路径长度可能会相应地减小。注意,是可能,而不是一定。但即使如此,我们仍然要将v加入到队列中等待处理,以保证这些结点的路径值在算法结束时被降至最优。

判断有无负环:
  如果某个点进入队列的次数超过N次则存在负环(SPFA无法处理带负环的图)

SPFA算法过程图解:

如下图求从源点a到其他点的最短路径:

1、首先建立起始点a到其余各点的最短路径表格,将源点元素(a)入队列:

 

2、源点元素(a)出队,对以a为起始点的所有边的终点依次进行松弛操作(此处有b,c,d三个点),此时路径表格状态为:

  

注意这里b,c,d都使d[]数组的值变小了,且不在queue队列中,所有入队。

3、队首元素b点出队,对以b为起始点的所有边的终点依次进行松弛操作(此处只有e点),此时路径表格状态为:

    

4、队首元素c点出队,对以c为起始点的所有边的终点依次进行松弛操作(此处有e,f两个点),此时路径表格状态为:

 

注意此时e在队列中,所以e不用再次入队列形成 d e f e这种队列形式,如这样会增加冗余运算。

5、队首元素d点出队,对以d为起始点的所有边的终点依次进行松弛操作(此处只有g这个点),此时路径表格状态为:

   

6、队首元素e点出队,对以e为起始点的所有边的终点依次进行松弛操作(此处有g这个点),因为d[e]+map[e][g](e到g点的距离)>d[g],故g不进队列,再说g本来就在队列里面了-,-此时队列的状态:

7、队首元素f点出队,对以f为起始点的所有边的终点依次进行松弛操作(此处有d,e,g三个点),此时路径表格状态为:

       

d点使路径表d[d]的值变大了,不如队列; e,f的最短路径估值变小了,e在队列中存在,f不存在。因此e不用入队了,f要入队。

8、队首元素g点出队,对以g为起始点的所有边的终点依次进行松弛操作(此处只有b点),此时路径表格状态为:

         

9、队首元素e点出队,对以e为起始点的所有边的终点依次进行松弛操作(此处只有g这个点),此时路径表格状态为:

         

d[e]+map[e][g]>d[g],故g不入队列

10、队首元素b点出队,对以b为起始点的所有边的终点依次进行松弛操作(此处只有e这个点),此时路径表格状态为:

     

当队列为空了,即计算出了从源点带所有点的最短距离, 由上表知:

a到b的最短路径是17;

关于算法能否结束?

由上面的演示我们知道,当queue为空的时候,我们就得出结果了。那是否存在queue不为空的时候呢,答案是肯定的。

对于不存在负权回路的图来说,上述算法是一定会结束的。因为算法在反复优化各个最短路径长度,总有一个时刻会进入“无法再优化”的局面,此时一旦队列读空,算法就结束了。然而,如果图中存在一条权值为负的回路,就糟糕了,算法会在其上反复运行(因为d[]加上一个负数肯定变下了,所以在有负环的情况下,会不断有数进入队列),通过“绕圈”来无休止地试图减小某些相关点的最短路径值。假如我们不能保证图中没有负权回路,一种“结束条件”是必要的。这种结束条件是什么呢?
      思考Bellman-Ford算法,它是如何结束的?显然,最朴素的Bellman-Ford算法不管循环过程中发生了什么,一概要循环|V|-1遍才肯结束。凭直觉我们可以感到,SPFA算法“更聪明一些”,就是说我们可以猜测,假如在SPFA中,一个点进入队列——或者说一个点被处理——超过了|V|次,那么就可以断定图中存在负权回路了。

【转载】https://blog.csdn.net/xiao_x_miss/article/details/9721509

求最短路径算法之SPFA算法相关推荐

  1. 【最短路径】:Dijkstra算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法

    求最短路径最常用的算法有: Dijkstra算法.SPFA算法.Bellman-Ford算法和Floyd-Warshall算法. Dijkstra算法.SPFA算法.Bellman-Ford算法这三个 ...

  2. #1093 : 最短路径·三:SPFA算法(邻接表)

    #1093 : 最短路径·三:SPFA算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋! 鬼屋中一共 ...

  3. 题目1008:最短路径问题(SPFA算法)

    问题来源 http://ac.jobdu.com/problem.php?pid=1008 问题描述 给定一个G(V,E)有向图,起点s以及终点t,求最短路径. 问题分析 典型的单源最短路径问题,可以 ...

  4. 最短路径问题(Floyd算法、Dijkstra算法、Bellman-Ford算法、SPFA算法)

    导入 最短路径问题是指在一幅带权图中,找出连接两个顶点之间的所有路径中,边权和最短的那一条.如下图就是一幅带权图,边上的数字就代表该边的权值.解决最短路径问题有多种不同的算法,本文将对它们的基本思想与 ...

  5. 图论-最短路径--3、SPFA算法O(kE)

    SPFA算法O(kE) 主要思想是:     初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束.     这个算 ...

  6. 单源最短路 Dijkstra算法 和 SPFA算法

    单源最短路 •从一个点出发,到达其他顶点的最短路径的长度. •基本操作:松弛 •d[u]+map[u, v]< d[v]这样的边(u,v)称为紧的(tense),可以对它进行松弛(relax): ...

  7. floyed算法、dijkstra算法、SPFA算法

    转自gzr的博客:https://www.cnblogs.com/TFLS-gzr/p/10381849.html,https://www.cnblogs.com/TFLS-gzr/p/1038746 ...

  8. I won't tell you this is about graph theory----zjfc bellman-ford算法与spfa算法

    题目描述 To think of a beautiful problem description is so hard for me that let's just drop them off. :) ...

  9. BellmanFord算法与SPFA算法

    Bellman-Ford Bellman-Ford 算法是一种用于计算带权有向图中单源最短路径(SSSP:Single-Source Shortest Path)的算法.该算法由 Richard Be ...

  10. 常用代码模板3——搜索与图论(Bellman-Ford算法 、spfa 算法、floyd算法、Kruskal算法、染色法、匈牙利算法 )

    目录 一.树与图的存储 二.树与图的遍历 (1) 深度优先遍历 -- 模板题 AcWing 846. 树的重心 (2) 宽度优先遍历 -- 模板题 AcWing 847. 图中点的层次 拓扑排序 -- ...

最新文章

  1. keras神经网络回归预测_如何使用Keras建立您的第一个神经网络来预测房价
  2. 如何组织公司的线下活动
  3. 物理化学 化学 动力学(下)
  4. java程序设计_JAVA基础程序设计之方法
  5. householder变换qr分解matlab_【基础教程】Matlab实现傅里叶变换
  6. 聚类算法 距离矩阵_快速且不需要超参的无监督聚类方法
  7. c++ string类_C++|细说STL string类概貌及底层细节
  8. 基于QGraphics的简易画板1
  9. mysql左联一对多_MySQL左连接多对一行
  10. C# 3.0新语言特性和改进
  11. 第一次想真正的认识自己
  12. hive出现内存溢出_hive问题处理
  13. java房屋租赁系统-房东租客系统PHP小程序
  14. 粮食在计算机中的应用,计算机监控系统在粮食仓储中的应用
  15. 计算机tpm管理,TPM管理工厂实施TPM可能面临的陷阱
  16. 徐荣谦《养好脾和肺 宝宝不积食不咳嗽长大个》【00】 序
  17. Cocos2d-x随记(2)-精灵移动
  18. win10笔记本使用ipad作为扩展屏
  19. Android Studio Text组件介绍
  20. No converter found for return value of type错误解决以及消息转化器简单分析

热门文章

  1. mysql安装方法及使用
  2. HFSS学习笔记—18.SMA模拟端口
  3. 屏幕录像软件camtasia2022汉化版好用的录屏软件
  4. 互联网大佬的枕边美女
  5. 实现基于SSM开发房屋租赁系统
  6. BLE低功耗蓝牙协议栈
  7. DJ设备市场现状及未来发展趋势
  8. uniapp微信支付方案
  9. web前端基础入门教程(非常详细)HTML+CSS+JavaScript
  10. 汉王数据导入java环境,汉王数据管理系统导入数据怎样进行数据更新,只导出一天的考勤数据?...