原文地址:http://lixing123.com/?p=280
Dijkstra算法(这个荷兰词真难读。。。不过Dijkstra是一位非常NB的计算机科学家,goto有害论、信号量和PV原语、哲学家聚餐问题、银行家算法等等,都是这位大牛搞出来的),是有向/无向加权图(就是每条边都有长度)中,计算两个点之间最短距离的有效方法,在使用堆排序的情况下,它的时间复杂度为O(Nlog(N+M)),(这里N代表节点数,M代表边数)很接近线性了,还是非常好的。
不过,Dijkstra算法有一个限制,就是它只适用于边长不为负的图。如果一张图里有负数长的边长,那么Dijkstra算法就不适用了。这时候就需要另外的算法了。
为什么不适用呢?其实很容易就可以找到反例。假设一张加权图,有的边长为负数。假设边长最小为-10,我们把所有的边长都加上10,就这就可以得到一张无负值加权图。此时用Dijkstra算法算出一个从节点s到节点t的最短路径L,L共包括n条边,总长为t;那么对于原图,每条边都要减去10,所以原图中L的长度是t-10*n。这是Diskstra算法算出的结果。
那么问题来了:对于加上10之后的图,假设还有一个从s到t的路径M,长度为t1,它共包括n1条边,比L包含的边长多,那么还原回来之后,每条边需要减去10,那么M的总长就是t1-10*n1。那么,是不是M的总长一定比L的总长更长一些呢?不一定。假如n1>n,也就是说M的边数比L的边数更多,那么M减去的要比L减去的更多,那么t1-10*n1<t-10*n是可能的。此时Dijkstra算法是不成立的。
另外,还有一种更简单的例子:假如一张图里有一个总长为负数的环,那么Dijkstra算法有可能会沿着这个环一直绕下去,绕到地老天荒。。。
另外,如果一张图里有负数边,但没有总长为负数的环,此时可以用Bellman-Ford算法计算。虽然它比Dijkstra慢了一些,但人家应用范围更广啊。
原文地址:http://blog.csdn.net/lixing333/article/details/41324313