TOP > グラフ 単一始点最短路 単一始点最短路(Dijkstra) 2018/03/23 • ei1333 説明 負辺のない単一始点全点間最短路を求めるアルゴリズム。負辺が無いと仮定すると、各地点でもっとも近いところから距離が確定していく。距離順でソートされたヒープを用いると、効率よく距離を確定していくことができる。 計算量 $O(E \log V)$ 実装例 dijkstra($g$, $s$):= 重み付きグラフ $g$ 上で、頂点 $s$ から全点間の最短コストを求める。到達できないとき, 型の最大値が格納される。 template< typename T > vector< T > dijkstra(WeightedGraph< T > &g, int s) { const auto INF = numeric_limits< T >::max(); vector< T > dist(g.size(), INF); using Pi = pair< T, int >; priority_queue< Pi, vector< Pi >, greater< Pi > > que; dist[s] = 0; que.emplace(dist[s], s); while(!que.empty()) { T cost; int idx; tie(cost, idx) = que.top(); que.pop(); if(dist[idx] < cost) continue; for(auto &e : g[idx]) { auto next_cost = cost + e.cost; if(dist[e.to] <= next_cost) continue; dist[e.to] = next_cost; que.emplace(dist[e.to], e.to); } } return dist; } 検証 AOJ GRL_1_A 単一始点最短経路 #define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_A" #include "../../template/template.cpp" #include "../template.cpp" #include "../dijkstra.cpp" int main() { int V, E, R; scanf("%d %d %d", &V, &E, &R); WeightedGraph< int > g(V); for(int i = 0; i < E; i++) { int a, b, c; scanf("%d %d %d", &a, &b, &c); g[a].emplace_back(b, c); } for(auto &dist : dijkstra(g, R)) { if(dist == numeric_limits< int >::max()) puts("INF"); else printf("%d\n", dist); } }