$\newcommand{\O}{\mathrm{O}}$

Dijkstra 法を Radix Heap を用いて高速化したアルゴリズム. 辺のコストが非負"整数"の場合に用いることができる高速化である.
アルゴリズムの理解には このスライド が参考になった.
元論文は "Faster Algorithms for the Shortest Path Problem" [Ahuja, Mehlhorn, Orlin, Tarjan 1990].
時間計算量: $\O ((n + m) \log(n \cdot MAX \_ VAL))$ (辺コストの最大値を $MAX \_ VAL$ とする)
#define impl(x, last) (x == last) ? 0 : 31 - __builtin_clz(x ^ last)
class RadixHeap{
public:
int last, size_;
vector<pair<int, int> > bucket_[32];
RadixHeap() : last(0), size_(0){}
inline pair<int, int> top(){
return pop(false);
}
inline bool empty(){
return !size_;
}
inline void push(int x, int val){
size_++, bucket_[impl(x, last)].emplace_back(x, val);
}
inline pair<int, int> pop(bool flag = true){
if(bucket_[0].empty()){
int id = 1;
while(bucket_[id].empty()) id++;
last = min_element(bucket_[id].begin(), bucket_[id].end())->first;
for(auto val : bucket_[id]){
bucket_[impl(val.first, last)].push_back(val);
}
bucket_[id].clear();
}
pair<int, int> res = bucket_[0].back();
if(flag) size_--, bucket_[0].pop_back();
return res;
}
};
class Dijkstra {
public:
struct edge{
int to, cost;
};
int V;
vector<vector<edge> > G;
vector<int> d;
using pii = pair<int, int>;
Dijkstra(int node_size) : V(node_size), G(V), d(V, numeric_limits<int>::max()){}
//無向グラフの場合
void add_edge(int u, int v, int cost){
G[u].push_back((edge){v, cost}), G[v].push_back((edge){u, cost});
}
void solve(int s){
RadixHeap que;
d[s] = 0;
que.push(0, s);
while(!que.empty()){
pii p = que.top();
que.pop();
int v = p.second;
if(d[v] < p.first) continue;
for(auto& w : G[v]){
if(d[w.to] > d[v] + w.cost){
d[w.to] = d[v] + w.cost;
que.push(d[w.to], w.to);
}
}
}
}
};