Advertisement
Guest User

Escape route

a guest
Mar 29th, 2021
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.21 KB | None | 0 0
  1. #include "escape_route.h"
  2. #include <bits/stdc++.h>
  3. using namespace std;
  4. using ll = long long;
  5.  
  6. // Struct for priority queue operations on index set [1, n]
  7. // push(i, v) overwrites value at position i if one already exists
  8. // decKey is faster but requires that the new key is smaller than the old one
  9. struct Prique {
  10.     const ll INF = 4 * (ll)1e18;
  11.     vector<pair<ll, int>> data;
  12.     const int n;
  13.  
  14.     Prique(int siz) : n(siz), data(2*siz, {INF, -1}) { data[0] = {-INF, -1}; }
  15.     void push(int i, ll v) {
  16.         data[i+n] = {v, (v >= INF ? -1 : i)};
  17.         for (i += n; i > 1; i >>= 1) data[i>>1] = min(data[i], data[i^1]);
  18.     }
  19.     void decKey(int i, ll v) {
  20.         for (int j = i+n; data[j].first > v; j >>= 1) data[j] = {v, i};
  21.     }
  22.     pair<ll, int> pop() {
  23.         auto res = data[1];
  24.         push(res.second, INF);
  25.         return res;
  26.     }
  27. };
  28.  
  29. const int N = 90;
  30. const ll INF = 1e18;
  31. ll tight_times[N][N][N];
  32. ll wts[N][N], cs[N][N];
  33. vector<pair<ll, int>> qs[N], ord[N];
  34.  
  35. vector<ll> calculate_necessary_time(
  36.         int n, int m, ll s, int q, vector<int> A, vector<int> B,
  37.         vector<ll> L, vector<ll> C, vector<int> U,
  38.             vector<int> V,  vector<ll> T) {
  39.  
  40.     // N: number of cities, N <= 90
  41.     // M: number of roads, M <= (N choose 2)
  42.     // S: seconds in a day, S <= 1e15
  43.     // Q: #queries, Q <= 3e6
  44.     // A, B, L, C: road i connects A[i] and B[i], takes L[i] seconds to traverse, and closes at time C[i]
  45.     // U, V, T: member j departs from city U[j] to city V[j] at time T[j]
  46.  
  47.     // Clear data
  48.     for (int i = 0; i < n; ++i) {
  49.         for (int j = 0; j < n; ++j) {
  50.             wts[i][j] = 0;
  51.             cs[i][j] = -1;
  52.         }
  53.         cs[i][i] = 0;
  54.     }
  55.     for (int i = 0; i < n; ++i) {
  56.         qs[i].clear();
  57.         qs[i].shrink_to_fit();
  58.         ord[i].clear();
  59.         ord[i].shrink_to_fit();
  60.     }
  61.  
  62.     // Assume complete graph
  63.     for (int j = 0; j < m; ++j) {
  64.         int a = A[j];
  65.         int b = B[j];
  66.         wts[a][b] = L[j];
  67.         wts[b][a] = L[j];
  68.         cs[a][b] = C[j] - L[j];
  69.         cs[b][a] = C[j] - L[j];
  70.     }
  71.  
  72.     // Calculate tight times : time to get from i to j, if we start at the last time we can take edge from i to x
  73.     for (int i = 0; i < n; ++i) {
  74.         for (int x = 0; x < n; ++x) {
  75.             for (int j = 0; j < n; ++j) tight_times[i][x][j] = INF; // Clear tight times
  76.             if (cs[i][x] == -1) continue;
  77.  
  78.             tight_times[i][x][i] = cs[i][x];
  79.  
  80.             Prique que(n);
  81.             for (int j = i; j != -1; j = que.pop().second) {
  82.                 ll base = tight_times[i][x][j];
  83.                 ll sec = base % s;
  84.                 ll nxt = base + (s - sec);
  85.                 for (int t = 0; t < n; ++t) {
  86.                     ll c = cs[j][t];
  87.                     if (c == -1) continue;
  88.  
  89.                     ll off = (c < sec ? nxt : base) + wts[j][t];
  90.                     if (off < tight_times[i][x][t]) {
  91.                         tight_times[i][x][t] = off;
  92.                         que.decKey(t, off);
  93.                     }
  94.                 }
  95.             }
  96.         }
  97.     }
  98.  
  99.     for (int j = 0; j < q; ++j) {
  100.         qs[U[j]].emplace_back(T[j], j);
  101.     }
  102.  
  103.     for (int i = 0; i < n; ++i) {
  104.         sort(qs[i].begin(), qs[i].end());
  105.         reverse(qs[i].begin(), qs[i].end());
  106.  
  107.         ord[i].resize(n);
  108.         for (int j = 0; j < n; ++j) ord[i][j] = make_pair(cs[i][j], j);
  109.  
  110.         sort(ord[i].begin(), ord[i].end());
  111.         reverse(ord[i].begin(), ord[i].end());
  112.     }
  113.  
  114.     vector<ll> ans(q, INF);
  115.     for (int i = 0; i < n; ++i) {
  116.         vector<int> inds(n, 0);
  117.         vector<ll> cur_dist(n, INF);
  118.         cur_dist[i] = 0;
  119.  
  120.         int qi = 0;
  121.  
  122.         Prique que(n);
  123.         que.decKey(i, -ord[i][inds[i]].first);
  124.         while(true) {
  125.             auto pr = que.pop();
  126.             ll next_time = -pr.first;
  127.  
  128.             // Answer queries
  129.             while(qi < qs[i].size() && qs[i][qi].first > next_time) {
  130.                 int ind = qs[i][qi].second;
  131.                
  132.                 // Answer if possible in one day
  133.                 ans[ind] = min(ans[ind], cur_dist[V[ind]]);
  134.                
  135.                 // Answer if need multiple days
  136.                 for (int t = 0; t < n; ++t) {
  137.                     if (cur_dist[t] <= s) ans[ind] = min(ans[ind], s - T[ind] + tight_times[t][t][V[ind]]);
  138.                 }
  139.  
  140.                 ++qi;
  141.             }
  142.            
  143.             if (next_time < 0) break;
  144.  
  145.             // Update distances
  146.             int j = pr.second;
  147.             int x = ord[j][inds[j]].second;
  148.             ++inds[j];
  149.  
  150.             if (inds[j] < n) que.decKey(j, -(ord[j][inds[j]].first - cur_dist[j]));
  151.  
  152.             for (int t = 0; t < n; ++t) {
  153.                 if (tight_times[j][x][t] >= s) continue;
  154.                
  155.                 ll off = cur_dist[j] + tight_times[j][x][t] - cs[j][x];
  156.                 if (off < cur_dist[t]) {
  157.                     cur_dist[t] = off;
  158.                     if (inds[t] < n) {
  159.                         que.decKey(t, -min(next_time, ord[t][inds[t]].first - off));
  160.                     }
  161.                 }
  162.             }
  163.         }
  164.     }
  165.     return ans;
  166. }
  167.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement