Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <algorithm>
- #include <chrono>
- using namespace std;
- class Heap {
- public:
- Heap() {}
- void Add(int val, float prio) {
- heap_.push_back(make_pair(prio, val));
- if ((int)pos_.size() < val+1) pos_.resize(val+1);
- int i = heap_.size() - 1;
- pos_[val] = i;
- ShiftUp(i);
- }
- int Pop() {
- Swap(0, heap_.size()-1);
- int val = heap_.back().second;
- heap_.pop_back();
- ShiftDown(0);
- return val;
- }
- int Size() {
- return heap_.size();
- }
- void DecreasePrio(int val, float new_prio) {
- heap_[pos_[val]].first = new_prio;
- ShiftUp(pos_[val]);
- }
- private:
- void Swap(int i, int j) {
- auto tmp = heap_[i];
- heap_[i] = heap_[j];
- heap_[j] = tmp;
- pos_[heap_[i].second] = i;
- pos_[heap_[j].second] = j;
- }
- void ShiftUp(int i) {
- while (i > 0) {
- int p = (i - 1) / 2;
- if (heap_[p] > heap_[i]) {
- Swap(p, i);
- i = p;
- } else {
- break;
- }
- }
- }
- void ShiftDown(int i) {
- while(true) {
- int less = i;
- int chld = 2*i+1;
- if (chld < (int)heap_.size() && heap_[chld].first < heap_[less].first) {
- less = chld;
- }
- ++chld;
- if (chld < (int)heap_.size() && heap_[chld].first < heap_[less].first) {
- less = chld;
- }
- if (less == i) break;
- Swap(less, i);
- i = less;
- }
- }
- vector<int> pos_;
- vector<pair<float,int>> heap_;
- };
- struct Graph {
- void AddEdge(int a, int b, float len) {
- if ((int)edges.size() < a+1) edges.resize(a+1);
- if ((int)edges.size() < b+1) edges.resize(b+1);
- edges[a].push_back(make_pair(b, len));
- edges[b].push_back(make_pair(a, len));
- }
- vector<vector<pair<int, float>>> edges;
- int n;
- };
- vector<int> Dijkstra(const Graph &g, int start, int end) {
- Heap queue;
- vector<float> distances(g.edges.size(), -1.0);
- vector<int> prev(g.edges.size(), -1);
- distances[start] = 0;
- queue.Add(start, 0);
- while (queue.Size() > 0) {
- int next = queue.Pop();
- for (auto edge : g.edges[next]) {
- float newDist = distances[next] + edge.second;
- if (distances[edge.first] < 0) {
- prev[edge.first] = next;
- distances[edge.first] = newDist;
- queue.Add(edge.first, newDist);
- } else if (distances[edge.first] > newDist) {
- prev[edge.first] = next;
- distances[edge.first] = newDist;
- queue.DecreasePrio(edge.first, newDist);
- }
- }
- }
- vector<int> res;
- int cur = end;
- while (cur != start) {
- res.push_back(cur);
- cur = prev[cur];
- }
- res.push_back(start);
- reverse(res.begin(), res.end());
- return res;
- }
- Graph g;
- int start, finish;
- void Load() {
- int m;
- cin >> m >> start >> finish;
- for (int i = 0; i < m; ++i) {
- int a, b;
- float len;
- cin >> a >> b >> len;
- g.AddEdge(a, b, len);
- }
- }
- int main() {
- Load();
- int sum;
- auto start_t = chrono::steady_clock::now();
- for (int i = 0; i < 1000; ++i) {
- vector<int> path = Dijkstra(g, start, finish);
- sum = 0;
- for (int v : path) sum += v;
- }
- auto end_t = chrono::steady_clock::now();
- cout << "sum: " << sum << " time: "
- << (chrono::duration_cast<chrono::milliseconds>(end_t - start_t).count()) / 1000.0 ;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement