Submission #379969

#TimeUsernameProblemLanguageResultExecution timeMemory
379969couplefireValley (BOI19_valley)C++17
100 / 100
563 ms59116 KiB
#include <bits/stdc++.h>
using namespace std;
#define MAXN 100005
#define INF 10000000000000000ll

int n, s, q, r;
vector<pair<int, long long>> adj[MAXN];
pair<int, int> edges[MAXN];
int tin[MAXN], tout[MAXN];
long long sumDepth[MAXN];
int depth[MAXN];
int curtime = 0;
int up[MAXN][32];
long long minUp[MAXN][32];
long long dp[MAXN];
bool isShop[MAXN];

void dfs(int v, int p = -1, long long d = 0, int dd = 0){
    sumDepth[v] = d;
    depth[v] = dd;
    tin[v] = ++curtime;
    dp[v] = INF;
    up[v][0] = p;
    for(int i = 1; i<32 && up[v][i-1] != -1; i++) up[v][i] = up[up[v][i-1]][i-1];
    for(auto u : adj[v]){
        if(u.first == p) continue;
        dfs(u.first, v, d+u.second, dd+1);
        dp[v] = min(dp[v], dp[u.first]+u.second);
    }
    if(isShop[v]) dp[v] = 0;
    tout[v] = ++curtime;
}

void getMinUp(int v, int p = -1){
    if(p == -1) minUp[v][0] = INF;
    else minUp[v][0] = dp[p]-sumDepth[p];
    for(int i = 1; i<32 && up[v][i-1] != -1; i++) minUp[v][i] = min(minUp[v][i-1], minUp[up[v][i-1]][i-1]);
    for(auto u : adj[v]){
        if(u.first == p) continue;
        getMinUp(u.first, v);
    }
}

bool isPar(int a, int b){
    return tin[a] <= tin[b] && tout[a] >= tout[b];
}

long long query(int v, int h){
    long long ans = INF;
    for(int i = 30; i>=0; i--){
        if((1<<i) <= h){
            ans = min(ans, minUp[v][i]);
            // cout << (1<<i) << endl;
            v = up[v][i];
            h -= (1<<i);
        }
    }
    return ans;
}

int main(){
    // freopen("a.in", "r", stdin);
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> s >> q >> r;
    --r;
    for(int i = 0; i<n-1; i++){
        int a, b; cin >> a >> b;
        --a; --b;
        int w; cin >> w;
        adj[a].push_back({b, w});
        adj[b].push_back({a, w});
        edges[i] = {a, b};
    }
    for(int i = 0; i<s; i++){
        int a; cin >> a; --a;
        isShop[a] = 1;
    }
    dfs(r);
    getMinUp(r);
    while(q--){
        int ind, v; cin >> ind >> v;
        --ind; --v;
        int a = edges[ind].first, b = edges[ind].second;
        if(depth[a] < depth[b]) swap(a, b);
        if(!(isPar(a, v) && isPar(b, v))){
            cout << "escaped" << endl;
            continue;
        }
        // cout << query(v, depth[v]-depth[a]) << endl;
        long long ans = sumDepth[v]+min(dp[v]-sumDepth[v], query(v, depth[v]-depth[a]));
        if(ans >= INF/2) cout << "oo" << endl;
        else cout << ans << endl;
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...