Loading docs/graph/shortest-path.md +7 −5 Original line number Diff line number Diff line Loading @@ -262,7 +262,7 @@ Johnson 和 Floyd 一样,是一种能求出无负环图上任意两点间最 任意两点间的最短路可以通过枚举起点,跑 $n$ 次 Bellman-Ford 算法解决,时间复杂度是 $O(n^2m)$ 的,也可以直接用 Floyd 算法解决,时间复杂度为 $O(n^3)$ 。 注意到堆优化的 Dijkstra 算法求单源最短路径的时间复杂度比 Bellman-Ford 更优,如果枚举起点,跑 $n$ 次 Dijkstra 算法,就可以在 $O((n^2+mn)\log m)$ 的时间复杂度内解决本问题,比上述跑 $n$ 次 Bellman-Ford 算法的时间复杂度更优秀。 注意到堆优化的 Dijkstra 算法求单源最短路径的时间复杂度比 Bellman-Ford 更优,如果枚举起点,跑 $n$ 次 Dijkstra 算法,就可以在 $O(nm\log m)$(取决于 Dijkstra 算法的实现)的时间复杂度内解决本问题,比上述跑 $n$ 次 Bellman-Ford 算法的时间复杂度更优秀,在稀疏图上也比 Floyd 算法的时间复杂度更加优秀。 但 Dijkstra 算法不能正确求解带负权边的最短路,因此我们需要对原图上的边进行预处理,确保所有边的边权均非负。 Loading Loading @@ -290,7 +290,7 @@ Johnson 算法则通过另外一种方法来给每条边重新标注边权。 接下来以每个点为起点,跑 $n$ 轮 Dijkstra 算法即可求出任意两点间的最短路了。 容易看出,该算法的时间复杂度是 $O(nm+(n^2+nm)\log m)$ 。 一开始的 Bellman-Ford 算法并不是时间上的瓶颈,若使用 `priority_queue` 实现 Dijkstra 算法,该算法的时间复杂度是 $O(nm\log m)$ 。 ### 正确性证明 Loading Loading @@ -318,7 +318,7 @@ Johnson 算法则通过另外一种方法来给每条边重新标注边权。 上面的新图中 $s \to t$ 的最短路的长度表达式由两部分组成,前面的边权和为原图中 $s \to t$ 的最短路,后面则是两点间的势能差。因为两点间势能的差为定值,因此原图上 $s \to t$ 的最短路与新图上 $s \to t$ 的最短路相对应。 到这里我们的正确性证明已经解决了一半——我们证明了重新标注边权后图上的最短路径仍然是原来的最短路径。接下来我们需要证明新图中所有边的边权非负,因为只有在非负权图上,Dijkstra 才能得出正确的结果。 到这里我们的正确性证明已经解决了一半——我们证明了重新标注边权后图上的最短路径仍然是原来的最短路径。接下来我们需要证明新图中所有边的边权非负,因为在非负权图上,Dijkstra 算法能够保证得出正确的结果。 根据三角形不等式,图上任意一边 $(u,v)$ 上两点满足: $h_v \leq h_u + w(u,v)$ 。这条边重新标记后的边权为 $w'(u,v)=w(u,v)+h_u-h_v \geq 0$ 。这样我们证明了新图上的边权均非负。 Loading @@ -331,8 +331,10 @@ Johnson 算法则通过另外一种方法来给每条边重新标注边权。 | Floyd | Bellman-Ford | Dijkstra | Johnson | | ---------- | ------------ | ------------------ | ------------------------ | | 每对结点之间的最短路 | 单源最短路 | 单源最短路 | 每对结点之间的最短路 | | 没有负环的图 | 任意图 | 非负权图 | 没有负环的图 | | $O(N^3)$ | $O(NM)$ | $O((N+M)\log M)$ | $O(NM+(N^2+NM)\log M)$ | | 没有负环的图 | 任意图(可以判定负环是否存在) | 非负权图 | 没有负环的图 | | $O(N^3)$ | $O(NM)$ | $O(M\log M)$ | $O(NM\log M)$ | 注:表中的 Dijkstra 算法在计算复杂度时均用 `priority_queue` 实现。 ## 输出方案 Loading Loading
docs/graph/shortest-path.md +7 −5 Original line number Diff line number Diff line Loading @@ -262,7 +262,7 @@ Johnson 和 Floyd 一样,是一种能求出无负环图上任意两点间最 任意两点间的最短路可以通过枚举起点,跑 $n$ 次 Bellman-Ford 算法解决,时间复杂度是 $O(n^2m)$ 的,也可以直接用 Floyd 算法解决,时间复杂度为 $O(n^3)$ 。 注意到堆优化的 Dijkstra 算法求单源最短路径的时间复杂度比 Bellman-Ford 更优,如果枚举起点,跑 $n$ 次 Dijkstra 算法,就可以在 $O((n^2+mn)\log m)$ 的时间复杂度内解决本问题,比上述跑 $n$ 次 Bellman-Ford 算法的时间复杂度更优秀。 注意到堆优化的 Dijkstra 算法求单源最短路径的时间复杂度比 Bellman-Ford 更优,如果枚举起点,跑 $n$ 次 Dijkstra 算法,就可以在 $O(nm\log m)$(取决于 Dijkstra 算法的实现)的时间复杂度内解决本问题,比上述跑 $n$ 次 Bellman-Ford 算法的时间复杂度更优秀,在稀疏图上也比 Floyd 算法的时间复杂度更加优秀。 但 Dijkstra 算法不能正确求解带负权边的最短路,因此我们需要对原图上的边进行预处理,确保所有边的边权均非负。 Loading Loading @@ -290,7 +290,7 @@ Johnson 算法则通过另外一种方法来给每条边重新标注边权。 接下来以每个点为起点,跑 $n$ 轮 Dijkstra 算法即可求出任意两点间的最短路了。 容易看出,该算法的时间复杂度是 $O(nm+(n^2+nm)\log m)$ 。 一开始的 Bellman-Ford 算法并不是时间上的瓶颈,若使用 `priority_queue` 实现 Dijkstra 算法,该算法的时间复杂度是 $O(nm\log m)$ 。 ### 正确性证明 Loading Loading @@ -318,7 +318,7 @@ Johnson 算法则通过另外一种方法来给每条边重新标注边权。 上面的新图中 $s \to t$ 的最短路的长度表达式由两部分组成,前面的边权和为原图中 $s \to t$ 的最短路,后面则是两点间的势能差。因为两点间势能的差为定值,因此原图上 $s \to t$ 的最短路与新图上 $s \to t$ 的最短路相对应。 到这里我们的正确性证明已经解决了一半——我们证明了重新标注边权后图上的最短路径仍然是原来的最短路径。接下来我们需要证明新图中所有边的边权非负,因为只有在非负权图上,Dijkstra 才能得出正确的结果。 到这里我们的正确性证明已经解决了一半——我们证明了重新标注边权后图上的最短路径仍然是原来的最短路径。接下来我们需要证明新图中所有边的边权非负,因为在非负权图上,Dijkstra 算法能够保证得出正确的结果。 根据三角形不等式,图上任意一边 $(u,v)$ 上两点满足: $h_v \leq h_u + w(u,v)$ 。这条边重新标记后的边权为 $w'(u,v)=w(u,v)+h_u-h_v \geq 0$ 。这样我们证明了新图上的边权均非负。 Loading @@ -331,8 +331,10 @@ Johnson 算法则通过另外一种方法来给每条边重新标注边权。 | Floyd | Bellman-Ford | Dijkstra | Johnson | | ---------- | ------------ | ------------------ | ------------------------ | | 每对结点之间的最短路 | 单源最短路 | 单源最短路 | 每对结点之间的最短路 | | 没有负环的图 | 任意图 | 非负权图 | 没有负环的图 | | $O(N^3)$ | $O(NM)$ | $O((N+M)\log M)$ | $O(NM+(N^2+NM)\log M)$ | | 没有负环的图 | 任意图(可以判定负环是否存在) | 非负权图 | 没有负环的图 | | $O(N^3)$ | $O(NM)$ | $O(M\log M)$ | $O(NM\log M)$ | 注:表中的 Dijkstra 算法在计算复杂度时均用 `priority_queue` 实现。 ## 输出方案 Loading