Submission #123013

#TimeUsernameProblemLanguageResultExecution timeMemory
123013model_codeValley (BOI19_valley)C++17
100 / 100
807 ms43140 KiB
#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;

const int maxn = 200005;
const int maxlg = 20;
const ll inf = 1LL << 60;

vector<pair<int, ll>> adj [maxn];
ll height [maxn];
int lvl [maxn];
ll dp [maxn];
bool store [maxn];
int start_time [maxn];
int end_time [maxn];
int cur_time;

void build_dp (int vertex, int parent, ll cur_height) {
  cur_time++;
  start_time[vertex] = cur_time;
  
  height[vertex] = cur_height;
  lvl[vertex] = lvl[parent] + 1;
  for (pair<int, ll> nxt : adj[vertex]) {
    if (nxt.first != parent) {
      build_dp(nxt.first, vertex, cur_height + nxt.second);
    }
  }

  if (store[vertex]) {
    dp[vertex] = height[vertex];
  } else {
    dp[vertex] = inf;
    for (pair<int, ll> nxt : adj[vertex]) {
      if (nxt.first != parent) {
        dp[vertex] = min(dp[vertex], dp[nxt.first]);
      }
    }
  }

  end_time[vertex] = cur_time;
}

bool is_parent (int u, int par) {
  return start_time[par] <= start_time[u] && end_time[u] <= end_time[par];
}

int jmp [maxn][maxlg];
ll ans_jmp [maxn][maxlg];

void build_jmp (int vertex, int parent) {
  jmp[vertex][0] = parent;
  if (dp[vertex] == inf) {
    ans_jmp[vertex][0] = inf;
  } else {
    ans_jmp[vertex][0] = dp[vertex] - 2 * height[vertex];
  }

  for (int i = 1; i < maxlg; i++) {
    jmp[vertex][i] = jmp[jmp[vertex][i - 1]][i - 1];
    ans_jmp[vertex][i] = min(ans_jmp[vertex][i - 1], ans_jmp[jmp[vertex][i - 1]][i - 1]);
  }

  for (pair<int, ll> nxt : adj[vertex]) {
    if (nxt.first != parent) {
      build_jmp(nxt.first, vertex);
    }
  }
}

ll query (int vertex, int forb) {
  if (!is_parent(vertex, forb)) {
    return -1;
  }

  ll cur_h = height[vertex];
  
  int diff = lvl[vertex] - lvl[forb];
  ll ans = inf;
  for (int i = maxlg - 1; i >= 0; i--) {
    if (diff & 1 << i) {
      ans = min(ans, ans_jmp[vertex][i]);
      vertex = jmp[vertex][i];
    }
  }
  ans = min(ans, ans_jmp[vertex][0]);

  if (ans != inf) {
    ans += cur_h;
  }
  
  return ans;
}

int main () {
  int vertexc, storec, queryc, root;
  cin >> vertexc >> storec >> queryc >> root;

  vector<pair<int, int>> edges;
  for (int i = 0; i < vertexc - 1; i++) {
    int u, v, w;
    cin >> u >> v >> w;

    adj[u].push_back(make_pair(v, w));
    adj[v].push_back(make_pair(u, w));
    edges.push_back(make_pair(u, v));
  }

  for (int i = 0; i < storec; i++) {
    int x;
    cin >> x;
    store[x] = true;
  }

  build_dp(root, root, 0);
  build_jmp(root, root);
  
  for (int i = 0; i < vertexc - 1; i++) {
    if (lvl[edges[i].first] < lvl[edges[i].second]) {
      swap(edges[i].first, edges[i].second);
    }
  }
  
  for (int i = 0; i < queryc; i++) {
    int forb_id, cur_vertex;
    cin >> forb_id >> cur_vertex;

    ll ans = query(cur_vertex, edges[forb_id - 1].first);
    if (ans == -1) {
      cout << "escaped" << '\n';
    } else if (ans == inf) {
      cout << "oo" << '\n';
    } else {
      cout << ans << '\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...