単一始点最短路 (Dijkstra; Heap)
概要
単一始点最短経路問題を解くアルゴリズム.負辺があるとやり直しが発生し,最悪負のループがあると終了しないため,ベルマンフォードを使うこと. 下の実装は優先度付きキューを利用している.
使い方
密なグラフでは $O(n^2)$ の実装 (graph/dijkstra-matrix.cc) を使うべき.負辺は計算量に影響し,最悪無限ループ.
計算量
$O((E+V)\log V)$.
実装
std::vector<Weight> dijkstra(const Graph &g, int s) {
const Weight INF = std::numeric_limits<Weight>::max() / 8;
using state = std::tuple<Weight, int>;
std::priority_queue<state> q;
std::vector<Weight> dist(g.size(), INF);
dist[s] = 0;
q.emplace(0, s);
while (q.size()) {
Weight d;
int v;
std::tie(d, v) = q.top();
q.pop();
d *= -1;
/* if(v == t) return d; */
if (dist[v] < d) continue;
for (auto &e : g[v]) {
if (dist[e.dst] > dist[v] + e.weight) {
dist[e.dst] = dist[v] + e.weight;
q.emplace(-dist[e.dst], e.dst);
}
}
}
return dist;
}