TOP > グラフ 単一始点最短路 単一始点最短路(Bellman-Ford) 2018/03/23 • ei1333 説明 単一始点全点間最短路を求めるアルゴリズム。単一始点全点間最短路を求めるアルゴリズム。負辺があっても動作する。また負閉路も検出する。 計算量 $O(VE)$ 実装例 bellman_ford($edges$, $V$, $s$):= $V$ 頂点の重み付き辺集合 $edges$ 上で、頂点 $s$ から全点間の最短コストを求める。到達できないとき, 型の最大値が格納される。負閉路を検出した時空列を返す。 template< typename T > vector< T > bellman_ford(Edges< T > &edges, int V, int s) { const auto INF = numeric_limits< T >::max(); vector< T > dist(V, INF); dist[s] = 0; for(int i = 0; i < V - 1; i++) { for(auto &e : edges) { if(dist[e.src] == INF) continue; dist[e.to] = min(dist[e.to], dist[e.src] + e.cost); } } for(auto &e : edges) { if(dist[e.src] == INF) continue; if(dist[e.src] + e.cost < dist[e.to]) return vector< T >(); } return dist; } 検証 AOJ GRL_1_B 単一始点最短経路(負の重みをもつ辺を含む #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_B" #include "../../template/template.cpp" #include "../template.cpp" #include "../bellman-ford.cpp" int main() { int V, E, R; scanf("%d %d %d", &V, &E, &R); Edges< int > es; for(int i = 0; i < E; i++) { int a, b, c; scanf("%d %d %d", &a, &b, &c); es.emplace_back(a, b, c); } auto dists = bellman_ford(es, V, R); if(dists.empty()) puts("NEGATIVE CYCLE"); for(auto &dist : dists) { if(dist == numeric_limits< int >::max()) puts("INF"); else printf("%d\n", dist); } }