-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
42 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,25 @@ | ||
--- | ||
documentation_of: //graph/shortest-path/bellman-ford.hpp | ||
title: Bellman-Ford (単一始点最短路) | ||
documentation_of: //graph/shortest-path/dijkstra.hpp | ||
--- | ||
|
||
## 概要 | ||
単一始点全点間最短路を求めるアルゴリズムです。負辺があっても動作します。経路上に負閉路がある場合はそれを検出します。 | ||
|
||
単一始点全点間最短路を求めるアルゴリズム. 負辺があっても動作する. また負閉路も検出する. | ||
# bellman_ford | ||
|
||
負閉路がない場合, 全ての頂点への最短路に含まれる辺の本数は $V - 1$ 本以下である. したがって $V - 1$ 回すべての辺を走査して最短路を更新すると, 最終的な最短路が求まる. | ||
```cpp | ||
template <typename T> | ||
vector<T> bellman_ford(const Edges<T> &edges, int n, int s) | ||
``` | ||
負閉路がある場合 $V$ 回目に更新があるときだが, 始点とある頂点との $2$ 点間のパスに負閉路が含まれることと同値ではないので注意すること(これを判定した場合は負閉路からその頂点に到達可能か判定するか, 始点とある頂点から到達できない頂点を予め削除しておく必要がある, 実装しなさーい!). | ||
頂点数 $n$ 、辺集合が `edges` からなる有向グラフについて、始点 $s$ から各頂点への最短路の重みを求め、それを返します。 | ||
## 使い方 | ||
* `bellman_ford(g, V, s)`: `V` 頂点の重み付きグラフ `g` で, 頂点 `s` から全点間の最短コストを求める. | ||
ただし、始点 $s$ からその頂点に到達できない場合は `T` の最大値、その頂点までの経路上に負閉路が存在する場合は `T` の最小値が格納されます。 | ||
## 制約 | ||
- $0 \leq s \lt n$ | ||
## 計算量 | ||
* $O(VE)$ | ||
* $O(V E)$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,32 @@ | ||
#pragma once | ||
|
||
#include "../graph-template.hpp" | ||
|
||
/** | ||
* @brief Bellman-Ford(単一始点最短路) | ||
* | ||
*/ | ||
template <typename T> | ||
vector<T> bellman_ford(const Edges<T> &edges, int V, int s) { | ||
vector<T> bellman_ford(const Edges<T> &edges, int n, int s) { | ||
const auto INF = numeric_limits<T>::max(); | ||
vector<T> dist(V, INF); | ||
const auto M_INF = numeric_limits<T>::min(); | ||
vector<T> dist(n, INF); | ||
dist[s] = 0; | ||
for (int i = 0; i < V - 1; i++) { | ||
for (int i = 0; i < n - 1; i++) { | ||
for (auto &e : edges) { | ||
if (dist[e.from] == INF) continue; | ||
dist[e.to] = min(dist[e.to], dist[e.from] + e.cost); | ||
} | ||
} | ||
for (auto &e : edges) { | ||
if (dist[e.from] == INF) continue; | ||
if (dist[e.from] + e.cost < dist[e.to]) return vector<T>(); | ||
vector<bool>negative(n); | ||
for(int i = 0; i < n; i++) { | ||
for (auto &e: edges) { | ||
if (dist[e.from] == INF) continue; | ||
if (dist[e.from] + e.cost < dist[e.to]) { | ||
dist[e.to] = dist[e.from] + e.cost; | ||
negative[e.to] = true; | ||
} | ||
if(negative[e.from]) { | ||
negative[e.to] = true; | ||
} | ||
} | ||
} | ||
for(int i = 0; i < n; i++) { | ||
if(negative[i]) dist[i] = M_INF; | ||
} | ||
return dist; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters