이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC optimize("O2")
#include<bits/stdc++.h>
#define ll long long
#define bit(mask, i) ((mask >> i) & 1)
using namespace std;
const ll INF = 1e18;
const int MOD = 1e9 + 7;
const int maxN = 1e5 + 5;
short LOG[maxN << 1];
struct RMQ {
  vector<vector<pair<int, int>>> rmq;
  RMQ() {};
  void build(const vector<pair<int, int>>& V) {
    int n = V.size();
    for (int i = 2; i <= n; ++i) LOG[i] = LOG[i >> 1] + 1;
    rmq.assign(25, V);
    int dep = 18;
    for (int i = 0; i < dep - 1; ++i)
      for (int j = 0; j < n; ++j) {
        rmq[i + 1][j] = min(rmq[i][j], rmq[i][min(n - 1, j + (1 << i))]);
      }
  }
  pair<int, int> query(int a, int b) {
    if (b <= a) return make_pair(INF, INF);
    int dep = LOG[b - a];
    return min(rmq[dep][a], rmq[dep][b - (1 << dep)]);
  }
};
int n, m, q, H;
vector<pair<int, int>> adj[maxN];
int C[maxN];
bitset<maxN> mark;
int cnt[maxN];
int depth[maxN], in[maxN], out[maxN];
int timer = 0;
ll res[maxN];
ll D[maxN];
ll dist[maxN];
struct LCA {
  RMQ rmq;
  vector<pair<int, int>> linear;
  LCA() {};
  LCA(int n) : linear(2 * n) {}
  bool in_subtree(int u, int v) {
    return in[u] <= in[v] && in[v] <= out[u];
  }
  void dfs(int u, int dep) {
    linear[timer] = {dep, u};
    in[u] = timer++;
    depth[u] = dep;
    cnt[u] = 1;
    for (auto [v, w] : adj[u]) {
      if (in[v] == -1) {
        dist[v] = dist[u] + w;
        dfs(v, dep + 1);
        cnt[u] += cnt[v];
        linear[timer++] = {dep, u};
      }
    }
    out[u] = timer;
  }
  void build(int root) {
    dfs(root, 0);
    rmq.build(linear);
  }
  int query(int a, int b) {
    a = in[a], b = in[b];
    return rmq.query(min(a, b), max(a, b) + 1).second;
  }
  ll get_dist(int a, int b) {
    return dist[a] + dist[b] - 2ll * dist[query(a, b)];
  }
};
LCA lca;
vector<int> sources;
void dfs(int u, int par, int ex) {
  if (mark[u]) sources.emplace_back(u);
  D[u] = INF;
  for (auto [v, w] : adj[u]) {
    if (v == par || v == ex) continue;
    dfs(v, u, ex);
  }
}
void bfs(int exclude) {
  queue<int> q;
  for (int u : sources) {
    D[u] = 0;
    q.push(u);
  }
  sources.clear();
  while (!q.empty()) {
    int u = q.front(); q.pop();
    for (auto [v, w] : adj[u]) {
      if (v == exclude) continue;
      if (D[v] > D[u] + w) {
        D[v] = D[u] + w;
        q.push(v);
      }
    }
  }
}
namespace IO {
    const int BUFSIZE = 1<<14;
    char buf[BUFSIZE + 1], *inp = buf;
    bool reacheof;
    char get_char() {
        if (!*inp && !reacheof) {
            memset(buf, 0, sizeof buf);
            int tmp = fread(buf, 1, BUFSIZE, stdin);
            if (tmp != BUFSIZE) reacheof = true;
            inp = buf;
        }
        return *inp++;
    }
    template<typename T>
    T get() {
        int neg = 0;
        T res = 0;
        char c = get_char();
        while (!(c >= '0' && c <= '9') && c != '-' && c != '+') c = get_char();
        if (c == '+') { neg = 0; }
        else if (c == '-') { neg = 1; }
        else res = c - '0';
        c = get_char();
        while (c >= '0' && c <= '9') {
            res = res * 10 + (c - '0');
            c = get_char();
        }
        return neg ? -res : res;
    }
};
int read() {
    return IO::get<int>();
}
void write(ll xo) {
    if (xo > 9)
        write(xo / 10);
    putchar(xo % 10 + '0');
}
signed main() {
  #define TASK "VALLET"
    if (fopen(TASK ".inp", "r")) {
      freopen(TASK ".inp", "r", stdin);
      freopen(TASK ".out", "w", stdout);
    }
  ios::sync_with_stdio(false);
  cin.tie(0); cout.tie(0);
  n = read();
  m = read();
  q = read();
  H = read();
  --H;
  vector<tuple<int, int, int>> edges;
  for (int i = 1; i < n; ++i) {
    int u, v, w;
    u = read();
    v = read();
    w = read();
    --u;
    --v;
    edges.emplace_back(u, v, w);
    adj[u].emplace_back(v, w);
    adj[v].emplace_back(u, w);
  }
  for (int i = 1; i <= m; ++i) {
    C[i] = read();
    --C[i];
    mark[C[i]] = true; 
  }
  for (int i = 0; i < n; ++i) {
    in[i] = out[i] = -1;
  }
  lca = LCA(n);
  lca.build(H);
  int idx = 0;
  vector<tuple<int, int, int>> heavy;
  int BLOCKS = sqrt(n);
  while (q--) {
    int I, R;
    I = read();
    R = read();
    --I;
    --R;
    auto [u, v, w] = edges[I];
    if (depth[u] < depth[v]) swap(u, v);
    if (lca.in_subtree(u, R)) {
      if (cnt[u] <= BLOCKS) {
        dfs(u, -1, v);
        bfs(v);
        res[++idx] = D[R];
      } else {
        heavy.emplace_back(u, R, ++idx);
      }
    } else res[++idx] = -1;
  }
  for (auto [u, R, pos] : heavy) {
    res[pos] = INF;
    for (int i = 1; i <= m; ++i) {
      if (lca.in_subtree(u, C[i])) {
        res[pos] = min(res[pos], lca.get_dist(R, C[i]));
      }
    }
  }
  for (int i = 1; i <= idx; ++i) {
    if (res[i] == -1) {
      putchar('e'); putchar('s'); putchar('c'); putchar('a'); putchar('p'); putchar('e'); putchar('d'); putchar('\n');
    }
    else if (res[i] == INF) {
      putchar('o');
      putchar('o');
      putchar('\n');
    }
    else {
      write(res[i]); 
      putchar('\n');
    }
  }
  return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
valley.cpp: In member function 'void LCA::dfs(int, int)':
valley.cpp:66:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
   66 |     for (auto [v, w] : adj[u]) {
      |               ^
valley.cpp: In function 'void dfs(int, int, int)':
valley.cpp:100:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  100 |   for (auto [v, w] : adj[u]) {
      |             ^
valley.cpp: In function 'void bfs(int)':
valley.cpp:115:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  115 |     for (auto [v, w] : adj[u]) {
      |               ^
valley.cpp: In function 'int main()':
valley.cpp:211:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  211 |     auto [u, v, w] = edges[I];
      |          ^
valley.cpp:223:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  223 |   for (auto [u, R, pos] : heavy) {
      |             ^
valley.cpp:170:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  170 |       freopen(TASK ".inp", "r", stdin);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:171:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  171 |       freopen(TASK ".out", "w", stdout);
      |       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict  | Execution time | Memory | Grader output | 
|---|
| Fetching results... |