Submission #1354048

#TimeUsernameProblemLanguageResultExecution timeMemory
1354048thewizardmanEvacuation plan (IZhO18_plan)C++20
100 / 100
350 ms82072 KiB
#pragma GCC optimize("Ofast,unroll-loops")
#include <bits/stdc++.h>
#define ms(x, y) memset(x, y, sizeof x)
#define sp ,' ',
#define el ,'\n'
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using l2 = array<ll, 2>;
using l3 = array<ll, 3>;

template<typename... Args>
inline void out(Args... args) {
  (cout << ... << args);
}

struct r {
  template<typename T>
  inline r& operator,(T& x) {
    cin >> x;
    return *this;
  }
} in;
#define in in,

int n, m, q, k, par[100005], sz[100005], de[100005], pa[17][100005];
ll dist[100005], mx[17][100005];
vector<l2> adj[100005], adj2[100005];
vector<l3> edges;
priority_queue<l2, vector<l2>, greater<l2>> pq;

int find(int x) {
  if (x == par[x]) return x;
  return par[x] = find(par[x]);
}

inline bool unite(int x, int y) {
  if ((x = find(x)) == (y = find(y))) return false;
  if (sz[x] > sz[y]) swap(x, y);
  par[x] = y;
  sz[y] += x;
  return true;
}

void dfs(int u, int p) {
  de[u] = de[p] + 1;
  pa[0][u] = p;
  for (auto [v, w]: adj2[u]) if (v != p) mx[0][v] = w;
  for (auto [v, w]: adj2[u]) if (v != p) dfs(v, u);
}

inline ll calc(int u, int v) {
  if (de[u] > de[v]) swap(u, v);
  int d = de[v] - de[u];
  ll ret = LLONG_MAX;
  for (int j = 0; j <= 16; j++) if ((d>>j) & 1) ret = min(ret, mx[j][v]), v = pa[j][v];
  if (u == v) return ret;
  for (int j = 16; j >= 0; j--) if (pa[j][u] != pa[j][v]) {
    ret = min(ret, mx[j][u]);
    ret = min(ret, mx[j][v]);
    u = pa[j][u];
    v = pa[j][v];
  }
  return min({ret, mx[0][u], mx[0][v]});
}

void solve() {
  memset(dist, 0x3f, sizeof dist);
  in n, m;
  while (m--) {
    int u, v, w; in u, v, w;
    adj[u].push_back({v, w});
    adj[v].push_back({u, w});
  }
  in k;
  while (k--) {
    int s; in s;
    pq.push({dist[s] = 0, s});
  }
  while (!pq.empty()) {
    auto [d, u] = pq.top(); pq.pop();
    if (d > dist[u]) continue;
    for (auto [v, w]: adj[u]) if (d + w < dist[v]) pq.push({dist[v] = d+w, v});
  }
  for (int i = 1; i <= n; i++) par[i] = i, sz[i] = 1;
  for (int u = 1; u <= n; u++) for (auto [v, w]: adj[u]) edges.push_back({min(dist[u], dist[v]), u, v});
  sort(edges.begin(), edges.end(), greater<>());
  for (auto [w, u, v]: edges) if (unite(u, v)) adj2[u].push_back({v, w}), adj2[v].push_back({u, w});
  dfs(1, 1);
  mx[0][1] = dist[1];
  // for (int i = 1; i <= n; i++) out(i sp mx[0][i] el);
  for (int j = 1; j <= 16; j++) for (int i = 1; i <= n; i++) {
    pa[j][i] = pa[j-1][pa[j-1][i]];
    mx[j][i] = min(mx[j-1][i], mx[j-1][pa[j-1][i]]);
  }
  // out("a" sp de[8] sp de[5] sp mx[0][8] el);
  in q;
  while (q--) {
    int u, v; in u, v;
    out(calc(u, v) el);
  }
}

signed main() {
  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  int t = 1;
  // in(t);
  while (t--) solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...