Guest User

Escape Route - 70p

a guest
Mar 29th, 2021
360
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.89 KB | None | 0 0
  1. #pragma GCC optimize("unroll-loops")
  2. #include "escape_route.h"
  3. #include <bits/stdc++.h>
  4. #define dbg() cerr <<
  5. #define name(x) (#x) << ": " << (x) << ' ' <<
  6.  
  7. using namespace std;
  8.  
  9. namespace {
  10.  
  11. struct Edge {
  12.   int to;
  13.   int64_t cost, bad_time;
  14. };
  15.  
  16. const int N = 90;
  17. const int64_t INF_LL = (int64_t)8e18 + 10;
  18.  
  19. int n;
  20. vector<Edge> adj[N];
  21. int64_t ans[N];
  22. bool vis[N];
  23.  
  24. void GetConstraints(int start_node, int64_t start_time) {
  25.   for (int i = 0; i < n; ++i) {
  26.     vis[i] = false;
  27.     ans[i] = -1;
  28.   }
  29.   ans[start_node] = start_time;
  30.  
  31.   while (true) {
  32.     pair<int64_t, int> best = {-1, -1};
  33.     for (int node = 0; node < n; ++node) {
  34.       if (vis[node] || ans[node] == -1) continue;
  35.       best = max(best, {ans[node], node});
  36.     }
  37.  
  38.     int node = best.second;
  39.     if (node == -1) break;
  40.  
  41.     vis[node] = true;
  42.     for (auto &e : adj[node]) {
  43.       if (ans[node] > e.bad_time) continue;
  44.  
  45.       int64_t curr = ans[node] - e.cost;
  46.       if (curr < 0) continue;
  47.       if (curr > ans[e.to]) {
  48.         ans[e.to] = curr;
  49.         assert(!vis[e.to]);
  50.       }
  51.     }
  52.   }
  53. }
  54.  
  55. int64_t dist[N];
  56.  
  57. void Dijkstra(int start_node, int64_t start_time, int64_t day_size) {
  58.   for (int i = 0; i < n; ++i) {
  59.     vis[i] = false;
  60.     dist[i] = INF_LL;
  61.   }
  62.   dist[start_node] = start_time;
  63.  
  64.   while (true) {
  65.     pair<int64_t, int> best = {INF_LL, -1};
  66.  
  67.     for (int node = 0; node < n; ++node) {
  68.       if (vis[node] || dist[node] == INF_LL) continue;
  69.       best = min(best, {dist[node], node});
  70.     }
  71.  
  72.     int node = best.second;
  73.     if (node == -1) break;
  74.  
  75.     vis[node] = true;
  76.     for (auto &e : adj[node]) {
  77.       int64_t nt = dist[node] + e.cost;
  78.       int64_t aux_t = dist[node] % day_size + e.cost;
  79.       if (aux_t > e.bad_time)
  80.         nt = (dist[node] + day_size - 1) / day_size * day_size + e.cost;
  81.       if (nt < dist[e.to]) {
  82.         dist[e.to] = nt;
  83.         assert(!vis[e.to]);
  84.       }
  85.     }
  86.   }
  87. }
  88.  
  89. vector<int64_t> buckets[N];
  90. vector<vector<int>> qrs[N];
  91. }
  92.  
  93. vector<long long> calculate_necessary_time(int N, int m, long long day_size, int q, vector<int> A, vector<int> B, vector<long long> L, vector<long long> C, vector<int> U, vector<int> V, vector<long long> T) {
  94.  
  95.   n = N;
  96.   for (int i = 0; i < m; ++i) {
  97.     int a = A[i], b = B[i];
  98.     int64_t l = L[i], c = C[i];
  99.     adj[a].emplace_back(Edge{b, l, c});
  100.     adj[b].emplace_back(Edge{a, l, c});
  101.   }
  102.  
  103. //  vector<vector<int64_t>> buckets(n);
  104.   for (int i = 0; i < n; ++i) {
  105.     buckets[i].emplace_back(0);
  106.     buckets[i].emplace_back(day_size);
  107.   }
  108.  
  109.   for (int i = 0; i < m; ++i) {
  110.     int64_t t = C[i] + 1 - L[i];
  111.     int node = A[i];
  112.    
  113.     GetConstraints(node, t);
  114.     for (int j = 0; j < n; ++j) {
  115.       if (ans[j] >= 0) buckets[j].emplace_back(ans[j]);
  116.     }
  117.  
  118.     node = B[i];
  119.     GetConstraints(node, t);
  120.     for (int j = 0; j < n; ++j) {
  121.       if (ans[j] >= 0) buckets[j].emplace_back(ans[j]);
  122.     }
  123.   }
  124.  
  125.   for (int i = 0; i < n; ++i) {
  126.     sort(buckets[i].begin(), buckets[i].end());
  127.     buckets[i].erase(unique(buckets[i].begin(), buckets[i].end()), buckets[i].end());
  128.   }
  129.  
  130. //  vector<vector<vector<int>>> qrs(n);
  131.   for (int i = 0; i < n; ++i) {
  132.     qrs[i].resize(buckets[i].size());
  133.   }
  134.  
  135.   for (int i = 0; i < q; ++i) {
  136.     int from = U[i];
  137.     int64_t t = T[i];
  138.     int pos = upper_bound(buckets[from].begin(), buckets[from].end(), t)
  139.       - buckets[from].begin() - 1;
  140.     qrs[from][pos].emplace_back(i);
  141.   }
  142.  
  143.   vector<long long> res(q);
  144.   for (int node = 0; node < n; ++node) {
  145.     for (int j = 0; j + 1 < (int)buckets[node].size(); ++j) {
  146.       int64_t t = buckets[node][j];
  147.       if (qrs[node][j].empty()) continue;
  148.      
  149.       Dijkstra(node, t, day_size);
  150.       for (int qid : qrs[node][j]) {
  151.         int64_t curr = dist[V[qid]];
  152.         if (curr > day_size) curr -= T[qid];
  153.         else curr -= t;
  154.  
  155.         res[qid] = curr;
  156.       }
  157.     }
  158.   }
  159.  
  160.   return res;
  161. }
  162.  
  163.  
Advertisement
Add Comment
Please, Sign In to add comment