Advertisement
Guest User

Untitled

a guest
Jan 23rd, 2021
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include <chrono>
  5.  
  6.  
  7. using namespace std;
  8.  
  9.  
  10. class Heap {
  11. public:
  12.   Heap() {}
  13.  
  14.  
  15.   void Add(int val, float prio) {
  16.     heap_.push_back(make_pair(prio, val));
  17.     if ((int)pos_.size() < val+1) pos_.resize(val+1);
  18.     int i = heap_.size() - 1;
  19.     pos_[val] = i;
  20.  
  21.     ShiftUp(i);
  22.   }
  23.  
  24.   int Pop() {
  25.     Swap(0, heap_.size()-1);
  26.     int val = heap_.back().second;
  27.     heap_.pop_back();
  28.     ShiftDown(0);
  29.     return val;
  30.   }
  31.  
  32.   int Size() {
  33.     return heap_.size();
  34.   }
  35.  
  36.   void DecreasePrio(int val, float new_prio) {
  37.     heap_[pos_[val]].first = new_prio;
  38.     ShiftUp(pos_[val]);
  39.   }
  40.  
  41. private:
  42.   void Swap(int i, int j) {
  43.     auto tmp = heap_[i];
  44.     heap_[i] = heap_[j];
  45.     heap_[j] = tmp;
  46.     pos_[heap_[i].second] = i;
  47.     pos_[heap_[j].second] = j;
  48.   }
  49.  
  50.  
  51.   void ShiftUp(int i) {  
  52.     while (i > 0) {
  53.       int p = (i - 1) / 2;
  54.       if (heap_[p] > heap_[i]) {
  55.         Swap(p, i);
  56.         i = p;
  57.       } else {
  58.         break;
  59.       }
  60.     }
  61.   }
  62.  
  63.   void ShiftDown(int i) {
  64.     while(true) {
  65.       int less = i;
  66.       int chld = 2*i+1;
  67.       if (chld < (int)heap_.size() && heap_[chld].first < heap_[less].first) {
  68.         less = chld;
  69.       }
  70.       ++chld;
  71.       if (chld < (int)heap_.size() && heap_[chld].first < heap_[less].first) {
  72.         less = chld;
  73.       }
  74.       if (less == i) break;
  75.       Swap(less, i);
  76.       i = less;
  77.     }
  78.   }
  79.  
  80.  
  81.   vector<int> pos_;
  82.   vector<pair<float,int>> heap_;
  83. };
  84.  
  85.  
  86. struct Graph {
  87.   void AddEdge(int a, int b, float len) {
  88.     if ((int)edges.size() < a+1) edges.resize(a+1);
  89.     if ((int)edges.size() < b+1) edges.resize(b+1);
  90.     edges[a].push_back(make_pair(b, len));
  91.     edges[b].push_back(make_pair(a, len));
  92.   }
  93.   vector<vector<pair<int, float>>> edges;
  94.   int n;
  95. };
  96.  
  97.  
  98. vector<int> Dijkstra(const Graph &g, int start, int end) {
  99.   Heap queue;
  100.   vector<float> distances(g.edges.size(), -1.0);
  101.   vector<int> prev(g.edges.size(), -1);
  102.   distances[start] = 0;
  103.   queue.Add(start, 0);
  104.   while (queue.Size() > 0) {
  105.     int next = queue.Pop();
  106.     for (auto edge : g.edges[next]) {
  107.       float newDist = distances[next] + edge.second;
  108.       if (distances[edge.first] < 0) {
  109.         prev[edge.first] = next;
  110.         distances[edge.first] = newDist;
  111.         queue.Add(edge.first, newDist);
  112.       } else if (distances[edge.first] > newDist) {
  113.         prev[edge.first] = next;
  114.         distances[edge.first] = newDist;
  115.         queue.DecreasePrio(edge.first, newDist);
  116.       }
  117.     }
  118.   }
  119.   vector<int> res;
  120.   int cur = end;
  121.   while (cur != start) {
  122.     res.push_back(cur);
  123.     cur = prev[cur];
  124.   }
  125.   res.push_back(start);
  126.   reverse(res.begin(), res.end());
  127.   return res;
  128. }
  129.  
  130.  
  131. Graph g;
  132. int start, finish;
  133.  
  134.  
  135. void Load() {
  136.   int m;
  137.   cin >> m >> start >> finish;
  138.   for (int i = 0; i < m; ++i) {
  139.     int a, b;
  140.     float len;
  141.     cin >> a >> b >> len;
  142.     g.AddEdge(a, b, len);
  143.   }
  144. }
  145.  
  146. int main() {
  147.   Load();
  148.   int sum;
  149.   auto start_t = chrono::steady_clock::now();
  150.   for (int i = 0; i < 1000; ++i) {
  151.     vector<int> path = Dijkstra(g, start, finish);
  152.     sum = 0;
  153.     for (int v : path) sum += v;
  154.   }
  155.   auto end_t = chrono::steady_clock::now();
  156.   cout << "sum: " << sum << " time: "
  157.     << (chrono::duration_cast<chrono::milliseconds>(end_t - start_t).count()) / 1000.0 ;
  158.  
  159.   return 0;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement