Submission #645567

#TimeUsernameProblemLanguageResultExecution timeMemory
645567alextodoranValley (BOI19_valley)C++17
0 / 100
117 ms30644 KiB
/**
 ____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|

**/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N_MAX = 100000;
const int BITS = 17;
const ll INF = LLONG_MAX / 2;

int N, S, Q, E;
bool shop[N_MAX + 2];
struct Edge {
    int u, v;
    int len;
    int to (int x) {
        return u ^ v ^ x;
    }
};
Edge edges[N_MAX + 2];

vector <int> adj[N_MAX + 2];
int pedge[N_MAX + 2];

int level[N_MAX + 2];
ll depth[N_MAX + 2];
ll minDown[N_MAX + 2];

void dfs (int u) {
    if (shop[u] == true) {
        minDown[u] = 0;
    } else {
        minDown[u] = INF;
    }
    for (int e : adj[u]) {
        int v = edges[e].to(u);
        if (v != edges[pedge[u]].to(u)) {
            pedge[v] = e;
            level[v] = level[u] + 1;
            depth[v] = depth[u] + edges[e].len;
            dfs(v);
            minDown[u] = min(minDown[u], minDown[v] + edges[e].len);
        }
    }
}

int ancestor[N_MAX + 2][BITS];
ll minPath[N_MAX + 2][BITS];
void precalc () {
    minDown[0] = INF;
    for (int k = 0; k < BITS; k++) {
        minPath[0][k] = INF;
    }
    for (int u = 1; u <= N; u++) {
        int v = edges[pedge[u]].to(u);
        ancestor[u][0] = v;
        if (minDown[u] == INF) {
            minPath[u][0] = INF;
        } else {
            minPath[u][0] = minDown[u] - depth[u];
        }
        if (minDown[v] != INF) {
            minPath[u][0] = min(minPath[u][0], minDown[v] - depth[v]);
        }
    }
    for (int k = 1; k < BITS; k++) {
        for (int u = 1; u <= N; u++) {
            ancestor[u][k] = ancestor[ancestor[u][k - 1]][k - 1];
            minPath[u][k] = min(minPath[u][k - 1], minPath[ancestor[u][k - 1]][k - 1]);
        }
    }
}

pair <int, ll> goUp (int u, int len) {
    ll mn = minDown[u];
    for (int k = 0; k < BITS; k++) {
        if ((len >> k) & 1) {
            mn = min(mn, minPath[u][k]);
            u = ancestor[u][k];
        }
    }
    return make_pair(u, mn);
}

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> N >> S >> Q >> E;
    for (int e = 1; e <= N - 1; e++) {
        cin >> edges[e].u >> edges[e].v >> edges[e].len;
        adj[edges[e].u].push_back(e);
        adj[edges[e].v].push_back(e);
    }
    for (int i = 1; i <= S; i++) {
        int u;
        cin >> u;
        shop[u] = true;
    }

    dfs(E);
    precalc();

    for (int i = 1; i <= Q; i++) {
        int e, u;
        cin >> e >> u;
        int v = edges[e].u;
        if (level[v] < level[edges[e].v]) {
            v = edges[e].v;
        }
        if (level[v] > level[u]) {
            cout << "escaped\n";
            continue;
        }
        int x; ll mn;
        tie(x, mn) = goUp(u, level[u] - level[v]);
        if (x != v) {
            cout << "escaped\n";
            continue;
        }
        if (mn == INF) {
            cout << "oo\n";
        } else {
            cout << depth[u] + mn << "\n";
        }
    }

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...