我们先看一下负权环为什么这么特殊:在一个图中,只要一个多边结构不是负权环,那么重复经过此结构时就会导致代价不断增大。在多边结构中唯有负权环会导致重复经过时代价不断减小,故在一些最短路径算法中可能会凭借不断重复经过负权环来得到权和为无穷小的最短路径,但因重复经过边不符合简单路径的定义导致这些算法跑最短路时要避免有负权环的出现。

这类算法说的就是Bellman-ford以及基于它进行优化的spfa了。由于负权环的出现导致这些算法的正确性失效。但这世上没有绝对的废物,我们也可以反过来利用这两种算法对负权环的敏感性来判断一个图内有无负权环。

结合一下这两个算法的原理,就能很简单地明白判负权回路的原理了:

1、Bellman-ford的原理即每次做一次枚举所有边进行一次大松弛操作后必有所有最短路径的第一条边(起点为源点的边)被确定(尽管我们并不确切地知道是哪一条边),被确定后,则会凭这条边再下一次大松弛操作再确定第二条边,以此类推。由于n个点的图的两点间最短路径最长有n条边,所以最多要n次大松弛就能把一个单源最短路求出(但实际上很多时候不到n次大松弛操作,就没有可松弛的了,即已经找到答案,可记录当前大松弛是否做过松弛操作,或基于该缺点改进为spfa)。但如果发现在n次大松弛操作后还有松弛操作可做,就说明负权回路出现了。时间复杂度O(nm)(m为边数),有点大。

2、SPFA则为针对Bellman-ford的缺点做的使每次做的松弛操作更有效的优化。发现在Bellman-ford第一次大松弛中只有松弛从源点出来的边才是有效的,松弛时当边的起点有效(被松弛过)时松弛操作才有效。那我们就不妨每次都只做有效的松弛操作,建一个队列,开始时将源点入队,每次从队头弹出head,尝试松弛所有head的邻接点,若松弛成功且该邻接点不在队中,就把它入队;否则什么也不干。时间复杂度为O(vm),v是一个平均值为2的常数。(因为当我们每次都做有效的松弛操作时,就会发现跑最短路快了很多,在大多数情况下可以吊打各个最短路算法。当然也特别容易被特殊数据卡,此时时间复杂度容易退化为O(nm))。类似的,spfa每做“一层”(层的概念类似于BFS的层)松弛操作就会确定所有最短路的一条边,故最极限的情况spfa做n层松弛操作就可以求出一个单源最短路了。

    每层松弛操作只会导致一个点最多出队一次,由于最多只有n层,所以每个点的出队次数最多应不超过n。不幸的是,spfa的松弛操作碰上负权环时,会发现,从环的某一点a开始松弛其他点时,由于是负权环,所以绕了一圈回来后一定会发现a要被松弛为更小的值b(环外的点松弛环上的点只会使b更小),故就有无限循环松弛出现。记录每个点的出队次数,当发现有一个点的出队次数大于n,即为有负权环出现了。

善意的提醒:解题推理时从某个结构的基础组成部分入手并扩展,常常遇到惊喜~~~

Bellman-ford算法与SPFA算法思想详解及判负权环(负权回路)的更多相关文章

  1. 数据结构与算法--最短路径之Bellman算法、SPFA算法

    数据结构与算法--最短路径之Bellman算法.SPFA算法 除了Floyd算法,另外一个使用广泛且可以处理负权边的是Bellman-Ford算法. Bellman-Ford算法 假设某个图有V个顶点 ...

  2. Bellman-Ford算法与SPFA算法详解

    PS:如果您只需要Bellman-Ford/SPFA/判负环模板,请到相应的模板部分 上一篇中简单讲解了用于多源最短路的Floyd算法.本篇要介绍的则是用与单源最短路的Bellman-Ford算法和它 ...

  3. 最短路径——Bellman-Ford算法以及SPFA算法

    说完dijkstra算法,有提到过朴素dij算法无法处理负权边的情况,这里就需要用到Bellman-Ford算法,抛弃贪心的想法,牺牲时间的基础上,换取负权有向图的处理正确. 单源最短路径 Bellm ...

  4. Bellman-ford算法、SPFA算法求解最短路模板

    Bellman-ford 算法适用于含有负权边的最短路求解,复杂度是O( VE ),其原理是依次对每条边进行松弛操作,重复这个操作E-1次后则一定得到最短路,如果还能继续松弛,则有负环.这是因为最长的 ...

  5. 最短路径算法 4.SPFA算法(1)

    今天所说的就是常用的解决最短路径问题最后一个算法,这个算法同样是求连通图中单源点到其他结点的最短路径,功能和Bellman-Ford算法大致相同,可以求有负权的边的图,但不能出现负回路.但是SPFA算 ...

  6. Floyd算法(一)之 C语言详解

    本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3 ...

  7. 最短路径算法之四——SPFA算法

    SPAF算法 求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm,该算法是西南交通大学段凡丁于1994年发表的. 它可以在O(kE)的时间复杂度内求出源点 ...

  8. 图论之最短路算法之SPFA算法

    SPFA(Shortest Path Faster Algorithm)算法,是一种求最短路的算法. SPFA的思路及写法和BFS有相同的地方,我就举一道例题(洛谷--P3371 [模板]单源最短路径 ...

  9. 最短路径问题---Floyed(弗洛伊德算法),dijkstra算法,SPFA算法

    在NOIP比赛中,如果出图论题最短路径应该是个常考点. 求解最短路径常用的算法有:Floyed算法(O(n^3)的暴力算法,在比赛中大概能过三十分) dijkstra算法 (堆优化之后是O(MlogE ...

随机推荐

  1. 应用安全 - 中间件漏洞 - Nostromo

     CVE-2011-0751 Date: 2011.3 类型: 路径遍历 PoC:https://nvd.nist.gov/vuln/detail/CVE-2011-0751 CVE-2019-162 ...

  2. java创建多线程实现并行计算任务处理

    1.直接上代码一看明白: package multithreadingTest; class fblib extends Thread{ public static Integer fb(Intege ...

  3. 【Linux开发】Linux磁盘管理

    第八章 Linux磁盘管理 [查看磁盘或者目录的容量 df 和 du] df 查看已挂载磁盘的总容量.使用容量.剩余容量等,可以不加任何参数,默认是按k为单位显示的:df常用参数有 –i -h -k ...

  4. linux/linux学习笔记-Shell基础(mooc)

    一.shell概述 shell根据ascII表,将命令翻译为0101...传给内核执行. 内核->shell翻译为命令->用户(操作的界面就是shell,shell=翻译官) linux标 ...

  5. eclipse sts 常规操作

    项目:右键 refresh 右键 maven -> update project 重新remove add project    重启软件,电脑 1.项目冗余 Package Explorer ...

  6. [转帖]mysql数据库主从配置

    mysql数据库主从配置 https://www.toutiao.com/i6680489302947791371/ 多做实验 其实挺简单的 很多东西 要提高自信 去折腾. 架构与我 2019-04- ...

  7. Dubbo 序列化协议 5 连问,你接得住不?

    1)dubbo 支持哪些通信协议? 2)支持哪些序列化协议? 3)说一下 Hessian 的数据结构? 4)PB 知道吗? 5)为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dub ...

  8. Java利用Base64编码和解码图片文件

    1.编码与解码代码如下所示: import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import jav ...

  9. NOI-LINUX

    先把配置背过吧: (set-background-color "gray15")(set-foreground-color "gray")(global-lin ...

  10. php编译完成后,module追加编译进php

    # 如果在编译的时候忘记添加某些模块,可以使用这种办法来重新编译添加! # 首先,进入PHP目录(未编译)的扩展目录 cd /home/soft/php-5.2.14/ext/ftp/ # 调用php ...