图论是离散数学中比较重要的一个分支;而图,恰好又是计算机中最重要的数据结构。所以今天开一个图论专题。
说道图,最先想到也是最常用的,自然就是怎样求最短路径。我们常说的最短路径指的是单源最短路径。常见的解决单源最短路径问题的算法有Dijkstra算法和Bellman-Ford算法。这两种算法都是基于动态规划思想实现的,所以这两个算法都有一个核心操作,就是松弛(Relax)。但是它们适用的范围不太一样。而对于多源最短路径,则有Floyd算法实现。
迪杰斯特拉算法
朴素Dijkstra算法遍历某一结点到其他结点的最短路径,其特点类似于BFS,层层向外扩展,直到找到终点为止。这种方法实现起来十分好理解,但是由于它遍历了大量的结点,导致它的时间复杂度达到了O(V^2+E)。若源点可达,复杂度变成O(V*logV+E*logV)。在稀疏图上,由于E=V*V/logV,时间复杂度可达O(V^2)。我们可以考虑用heap去优化Dijkstra,这样能使得复杂度进一步降低,获得O(VlogV+E)。
贝尔曼-福特算法
Dijkstra算法有个局限性,就是它只能求解单源、正权的最短路径。一旦图上含负权,Dijkstra就无能为力了。原因很好理解,Dijkstra在贪心地寻找当前距源点最小距离的点时,有可能先走过次优点,再走过该负权,会使得最短距离更小。反例很好举&#x