http://www.cnblogs.com/mengxm-lincf/archive/2012/02/11/2346288.html

其实我一直存在疑惑是什么导致dijkstra不能处理负权图?

今日偶见某大牛说一句“dijkstra选定一个节点后节点值不在改变”,方才大悟。

本质上就是dijkstra选点方式导致的(即贪心),只针对目前的情况作出最好的判断

1)在非负权图中这点是没有错的

2)在负权图中就出错了,如

0 2 4

2 0 -3

4 -3 0

为什么呢?

证明dijkstra可行的最重要定理:即当i被选中时,dist(i)=min{w(s->i)}

定理证明:若不存在一个节点j可以松弛i,那么显然定理成立,否则必存在某一节点j,dist(i)>w(j,i)+dist(j),那么由于在非负权图中所以w(j,i)>0,则dist(i)>dist(j),那么在选择i之前j一定已经被选走,由此推出矛盾,定理证毕。由定理可知贪心在此的正确性。

看到前面证明中关键点(红字处),如果在负权图中那么w(j,i)>0就不一定成立,则定理也就不成立了,贪心也必然是错误的。

再看bellman-ford,假设图G存在最短路径a->b->c->d

循环松弛:第一次找到a->b

第二次找到a->b->c

第三次找到a->b->c->d

但是注意图G至少存在1条最短路,第几次循环松弛就是同时确定所有最短路的第几个节点(注意是第几个节点而不是具体的哪一个点),也就是说在bellman-ford的操作中无法再某一时刻确定某一个节点的dist是最短路径值,但是可以确定当n-1循环松弛后所有最短路一定确定了,因为图G最长的最短路其边数一定小于等于n-1,所以从一条最短路的角度看n-1次松弛后最短路径一定确定了。

再看bellman-ford的负权回路检验,dist(i)>dist(j)+w(j,i)。

为什么这个式子成立即有负权回路。显然若是不存在负权回路那么根据最短路的性质上式不可能成立,因为经过n-1循环松弛所有最短路都已确定那么dist是原点到个点的最短距离,根据最短路的最优子结构,dist(i)<=dist(j)+w(j,i)。

简证:

显然若dist(j)不是最后一轮松弛才出现,则在下一轮松弛中会使dist(i)更新,那么就不会出现上式,那也就是说i必须在以j为终点的最短路中,s->i->j,如果没有i,则dist(j)不可能在最后一轮松弛中才出现,现在可以发现有一个循环i->j,j->i,且这个循环使j的值不断减小,那么这个循环只能是负权的,证毕。

注意dist(i)>dist(j)+w(j,i)可行前提条件是dist是最短路径,由于dijkstra在负权图的无法得出正确最短路径所以无法使用该使检查是否存在负权回路。

floyd可以检查回路(无论正负)

但是floyd的负权检查可以简单一点,即dist[i][i]<INF,判断i终值是否小于初始值,因为若存在负权回路那么必有至少一个点其值在n次循环松弛后由于负权回路的原因小于其初始值。注意这种简化检验只适合于问题:原点不确定的图中是否存在负权回路。同理dist[i][i]>INF,判断i终值是否大于初始值,判断正权回路。

dijkstra,bellman-ford,floyd分析比较的更多相关文章

  1. 图论——最短路径 Dijkstra算法、Floyd算法

    1.弗洛伊德算法(Floyd) 弗洛伊算法核心就是三重循环,M [ j ] [ k ] 表示从 j 到 k 的路径,而 i 表示当前 j 到 k 可以借助的点:红色部分表示,如果 j 到 i ,i 到 ...

  2. ACM/ICPC 之 最短路径-Bellman Ford范例(POJ1556-POJ2240)

    两道Bellman Ford解最短路的范例,Bellman Ford只是一种最短路的方法,两道都可以用dijkstra, SPFA做. Bellman Ford解法是将每条边遍历一次,遍历一次所有边可 ...

  3. poj1860 bellman—ford队列优化 Currency Exchange

    Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 22123   Accepted: 799 ...

  4. PKU 1932 XYZZY(Floyd+Bellman||Spfa+Floyd)

    题目大意:原题链接 给你一张图,初始你在房间1,初始生命值为100,进入每个房间会加上那个房间的生命(可能为负),问是否能到达房间n.(要求进入每个房间后生命值都大于0) 解题思路: 解法一:Floy ...

  5. Bellman - Ford 算法解决最短路径问题

    Bellman - Ford 算法: 一:基本算法 对于单源最短路径问题,上一篇文章中介绍了 Dijkstra 算法,但是由于 Dijkstra 算法局限于解决非负权的最短路径问题,对于带负权的图就力 ...

  6. uva 558 - Wormholes(Bellman Ford判断负环)

    题目链接:558 - Wormholes 题目大意:给出n和m,表示有n个点,然后给出m条边,然后判断给出的有向图中是否存在负环. 解题思路:利用Bellman Ford算法,若进行第n次松弛时,还能 ...

  7. C++编程练习(11)----“图的最短路径问题“(Dijkstra算法、Floyd算法)

    1.Dijkstra算法 求一个顶点到其它所有顶点的最短路径,是一种按路径长度递增的次序产生最短路径的算法. 算法思想: 按路径长度递增次序产生算法: 把顶点集合V分成两组: (1)S:已求出的顶点的 ...

  8. 最短路径——Dijkstra算法和Floyd算法

    Dijkstra算法概述 Dijkstra算法是由荷兰计算机科学家狄克斯特拉(Dijkstra)于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有向图(无 ...

  9. Bellman—Ford算法思想

    ---恢复内容开始--- Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题.对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射.对图G ...

  10. 【转载】Dijkstra算法和Floyd算法的正确性证明

      说明: 本文仅提供关于两个算法的正确性的证明,不涉及对算法的过程描述和实现细节 本人算法菜鸟一枚,提供的证明仅是自己的思路,不保证正确,仅供参考,若有错误,欢迎拍砖指正   ----------- ...

随机推荐

  1. [转]SQL中使用WITH AS提高性能-使用公用表表达式(CTE)简化嵌套SQL

    一.WITH AS的含义     WITH AS短语,也叫做子查询部分(subquery factoring),可以让你做很多事情,定义一个SQL片断,该SQL片断会被整个SQL语句所用到.有的时候, ...

  2. PHP学习笔记 - 进阶篇(5)

    PHP学习笔记 - 进阶篇(5) 正则表达式 什么叫正则表达式 正则表达式是对字符串进行操作的一种逻辑公式,就是用一些特定的字符组合成一个规则字符串,称之为正则匹配模式. $p = '/apple/' ...

  3. javascript笔记——placehold

    <input type="text" name="搜索" value="搜索" placeholder="搜索" ...

  4. Normalize [ 浏览器渲染格式化 ]

    /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ /** * 1. Set default font family to san ...

  5. Z-Stack内部API 小结

    Z-Stack是TI推出的全功能ZigBee协议栈,通过了ZigBee联盟的兼容性平台测试,包含如下几个组件. 1. HAL,硬件抽象层 2. OSAL,操作系统抽象层 3. ZigBee Stack ...

  6. excl剔除不合格数据求平均值

    excl剔除不合格数据求平均值 trimmean函数 正态分布: CONFIDENCE.NORM 函数

  7. C# 代理HTTP请求

    目的: 应该有不少人需要去某些网站不停爬取数据,有时会使用HTTPRequest一直请求某个网站的某个网址.有的网站比如 QQ空间,赶集网(这是我测试的网站),不停刷新会提醒你的账号异常,可能会查封你 ...

  8. vs2013编译qt程序后中文出现乱码

    我的vs是2013版的,qt是5.4.2,在使用vc将程序编译好后并运行时在界面上输出的中文出现了乱码,在网上找了很长时间终于找到了解决方法: QString str = QStringLiteral ...

  9. stl::find,find_if,find_if_not

    //满足特定条件下的实现,回调函数template<class InputIt, class UnaryPredicate> InputIt find_if(InputIt first, ...

  10. javascript之数据推送

    我们使用ajax与后台服务进行交互,常常是通过触发事件来单次交互,但对于有些web应用来说,需要前台与后台保持长连接,前端不定时地接收后台推送的数据信息, 例如:股票行情分析.聊天室和网页在线游戏等. ...