Loading [MathJax]/jax/output/CommonHTML/jax.js
My Algorithm : kopricky アルゴリズムライブラリ

kopricky アルゴリズムライブラリ

Dijkstra with Radix Heap

コードについての説明(個人的メモ)

Dijkstra 法を Radix Heap を用いて高速化したアルゴリズム. 辺のコストが非負"整数"の場合に用いることができる高速化である.
アルゴリズムの理解には このスライド が参考になった.
元論文は "Faster Algorithms for the Shortest Path Problem" [Ahuja, Mehlhorn, Orlin, Tarjan 1990].

時間計算量: O((n+m)log(nMAX_VAL)) (辺コストの最大値を MAX_VAL とする)

コード(nMAX_VAL が int に収まることを仮定した場合の実装)

  1. #define impl(x, last) (x == last) ? 0 : 31 - __builtin_clz(x ^ last)
  2.  
  3. class RadixHeap{
  4. public:
  5. int last, size_;
  6. vector<pair<int, int> > bucket_[32];
  7.  
  8. RadixHeap() : last(0), size_(0){}
  9.  
  10. inline pair<int, int> top(){
  11. return pop(false);
  12. }
  13. inline bool empty(){
  14. return !size_;
  15. }
  16. inline void push(int x, int val){
  17. size_++, bucket_[impl(x, last)].emplace_back(x, val);
  18. }
  19. inline pair<int, int> pop(bool flag = true){
  20. if(bucket_[0].empty()){
  21. int id = 1;
  22. while(bucket_[id].empty()) id++;
  23. last = min_element(bucket_[id].begin(), bucket_[id].end())->first;
  24. for(auto val : bucket_[id]){
  25. bucket_[impl(val.first, last)].push_back(val);
  26. }
  27. bucket_[id].clear();
  28. }
  29. pair<int, int> res = bucket_[0].back();
  30. if(flag) size_--, bucket_[0].pop_back();
  31. return res;
  32. }
  33. };
  34.  
  35. class Dijkstra {
  36. public:
  37. struct edge{
  38. int to, cost;
  39. };
  40. int V;
  41. vector<vector<edge> > G;
  42. vector<int> d;
  43. using pii = pair<int, int>;
  44. Dijkstra(int node_size) : V(node_size), G(V), d(V, numeric_limits<int>::max()){}
  45. //無向グラフの場合
  46. void add_edge(int u, int v, int cost){
  47. G[u].push_back((edge){v, cost}), G[v].push_back((edge){u, cost});
  48. }
  49. void solve(int s){
  50. RadixHeap que;
  51. d[s] = 0;
  52. que.push(0, s);
  53. while(!que.empty()){
  54. pii p = que.top();
  55. que.pop();
  56. int v = p.second;
  57. if(d[v] < p.first) continue;
  58. for(auto& w : G[v]){
  59. if(d[w.to] > d[v] + w.cost){
  60. d[w.to] = d[v] + w.cost;
  61. que.push(d[w.to], w.to);
  62. }
  63. }
  64. }
  65. }
  66. };

verify 用の問題

AOJ : Single Source Shortest Path 提出コード