Submission #1042823

#TimeUsernameProblemLanguageResultExecution timeMemory
1042823avighnaValley (BOI19_valley)C++17
100 / 100
167 ms64208 KiB
#include <bits/stdc++.h>

typedef long long ll;

const ll inf = 1e15;

struct Edge {
  ll u, v, w;
};

int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);

  ll n, s, q, e;
  std::cin >> n >> s >> q >> e;
  std::vector<std::vector<std::pair<ll, ll>>> adj(n + 1);
  std::vector<Edge> edges;
  for (ll i = 0, u, v, w; i < n - 1; ++i) {
    std::cin >> u >> v >> w;
    adj[u].push_back({v, w});
    adj[v].push_back({u, w});
    edges.push_back({u, v, w});
  }

  std::vector<ll> d(n + 1), depth(n + 1);
  std::function<void(ll, ll)> dfs;
  std::vector<ll> start(n + 1), end(n + 1);
  ll timer = 0;
  std::vector<std::vector<ll>> lift(n + 1, std::vector<ll>(20));
  dfs = [&](ll node, ll par) {
    start[node] = timer++;
    for (auto &[i, wt] : adj[node]) {
      if (i == par) {
        continue;
      }
      lift[i][0] = node;
      d[i] = d[node] + wt;
      depth[i] = depth[node] + 1;
      dfs(i, node);
    }
    end[node] = timer - 1;
  };
  lift[e][0] = e;
  dfs(e, 0);

  std::vector<bool> shop(n + 1);
  for (ll i = 0, v; i < s; ++i) {
    std::cin >> v;
    shop[v] = true;
  }

  // dp[i] = - 2 * d[i] + min{d[x] forall shop[x] == true, x is in the subtree
  // of i}
  std::vector<ll> dp(n + 1);
  std::function<void(ll, ll)> dfs2;
  dfs2 = [&](ll node, ll par) {
    if (shop[node]) {
      dp[node] = d[node];
    } else {
      dp[node] = inf;
    }
    for (auto &[i, wt] : adj[node]) {
      if (i == par) {
        continue;
      }
      dfs2(i, node);
      dp[node] = std::min(dp[node], dp[i]);
    }
  };
  dfs2(e, 0);
  for (ll i = 1; i <= n; ++i) {
    if (dp[i] != inf) {
      dp[i] -= 2 * d[i];
    }
  }

  std::vector<std::vector<ll>> lmin(n + 1, std::vector<ll>(20));
  for (ll i = 1; i <= n; ++i) {
    lmin[i][0] = dp[i];
  }
  for (ll bt = 1; bt < 20; ++bt) {
    for (ll i = 1; i <= n; ++i) {
      lmin[i][bt] = std::min(lmin[i][bt - 1], lmin[lift[i][bt - 1]][bt - 1]);
      lift[i][bt] = lift[lift[i][bt - 1]][bt - 1];
    }
  }

  auto binary_lift = [&](ll x, ll c) {
    ll ans = inf;
    for (ll bt = 0; bt < 20; ++bt) {
      if (c & (1 << bt)) {
        ans = std::min(ans, lmin[x][bt]);
        x = lift[x][bt];
      }
    }
    return ans;
  };

  while (q--) {
    ll i, r;
    std::cin >> i >> r;
    --i;
    auto [u, v, wt] = edges[i];
    if (d[u] > d[v]) {
      std::swap(u, v);
    }
    if (!(start[v] <= start[r] and start[r] <= end[v])) {
      std::cout << "escaped\n";
      continue;
    }
    ll val = binary_lift(r, depth[r] - depth[v] + 1);
    if (val == inf) {
      std::cout << "oo\n";
    } else {
      std::cout << val + d[r] << '\n';
    }
  }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...