Submission #1277316

#TimeUsernameProblemLanguageResultExecution timeMemory
1277316_filya_Valley (BOI19_valley)C++20
100 / 100
184 ms69128 KiB
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;

const int N = 1e5 + 50, lgN = 22;
ll par[N], lifting1[N][lgN], lifting2[N][lgN], lifting3[N][lgN], nv[N], shop[N], depth[N], inf = 1e18;
int n, s, q, e;
vector<pair<int, ll>> G[N];

void dfs(int s, int p, ll w) {
    par[s] = p;
    depth[s] = depth[p] + 1;
    lifting2[s][0] = w;
    nv[s] = (shop[s] ? 0 : inf);
    for (auto u : G[s]) {
        if (u.first == p) continue;
        dfs(u.first, s, u.second);
        nv[s] = min(nv[s], nv[u.first] + u.second);
    }
}

int kth_parent(int node, int k) {
    if (k > n) { return -1; }
    int at = node;
    for (int pow = 0; pow <= lgN; pow++) {
        if ((k & (1 << pow)) != 0) {
            at = lifting1[at][pow];
            if (at == -1) { break; }
        }
    }
    return at;
}

int lca(int n1, int n2) {
    if (depth[n1] < depth[n2]) { return lca(n2, n1); }
    n1 = kth_parent(n1, depth[n1] - depth[n2]);
    if (n1 == n2) {
        return n2;
    }
    for (int i = lgN; i >= 0; i--) {
        if (lifting1[n1][i] != lifting1[n2][i]) {
            n1 = lifting1[n1][i];
            n2 = lifting1[n2][i];
        }
    }
    return lifting1[n1][0];
}

int main()
{
// 	ifstream cin("input.txt");
//     ofstream cout("output.txt");
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cin >> n >> s >> q >> e;
    vector<pair<int, int>> edges;
    for (int i = 0; i < n - 1; i++) {
        int a, b, w; cin >> a >> b >> w;
        G[a].push_back({b, w});
        G[b].push_back({a, w});
        edges.push_back({a, b});
    }
    while(s--) {
        int c; cin >> c;
        shop[c] = 1;
    }
    dfs(e, e, 0);
    for (auto& [a, b] : edges) {
        if (depth[a] < depth[b]) swap(a, b);
    }
    for (int i = 1; i <= n; i++) {
        lifting1[i][0] = par[i];
        lifting3[i][0] = min(nv[i], nv[par[i]] + lifting2[i][0]);
    }
    for (int lg = 1; lg < lgN; lg++) {
        for (int i = 1; i <= n; i++) {
            lifting1[i][lg] = lifting1[lifting1[i][lg - 1]][lg - 1];
            lifting2[i][lg] = lifting2[lifting1[i][lg - 1]][lg - 1] + lifting2[i][lg - 1];
            lifting3[i][lg] = min(lifting3[i][lg - 1], lifting3[lifting1[i][lg - 1]][lg - 1] + lifting2[i][lg - 1]);
        }
    }
    while(q--) {
        int i, r; cin >> i >> r;
        int u = edges[i - 1].first;
        if (lca(u, r) == u) {
            int w = depth[r] - depth[u];
            ll res = nv[r], curdist = 0;
            for (int lg = 0; lg < lgN; lg++) {
                if (w % 2) {
                    res = min(res, lifting3[r][lg] + curdist);
                    curdist += lifting2[r][lg];
                    r = lifting1[r][lg];
                }
                w /= 2;
            }
            if (res >= inf) cout << "oo\n";
            else cout << res << '\n';
        } else {
            cout << "escaped\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...