제출 #1078546

#제출 시각아이디문제언어결과실행 시간메모리
1078546MighilonValley (BOI19_valley)C++17
100 / 100
122 ms40120 KiB
#include <bits/stdc++.h>
using namespace std;
 
#ifdef DEBUG
#include "../Library/debug.h"
#else
#define dbg(x...)
#endif
 
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl; 
 
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define F0R(i, a) for (int i = 0; i < (a); ++i)
#define FORd(i, a, b) for (int i = (b) - 1; i >= (a); --i)
#define F0Rd(i, a) for (int i = (a) - 1; i >= 0; --i)
#define trav(a, x) for (auto& a : x)
#define f first 
#define s second
#define pb push_back
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
 
const char nl = '\n';
const int INF = 1e9;
const int MOD = 1e9 + 7;

void solve(){
    int n, s, q, e;
    cin >> n >> s >> q >> e; --e;
    vector<vi> adj(n);
    vector<array<int, 3>> edge(n - 1);
    vector<bool> shop(n);
    F0R(i, n - 1){
        int a, b, w;
        cin >> a >> b >> w;
        a--, b--;
        edge[i][0] = a ^ b;
        edge[i][1] = w;
        adj[a].pb(i);
        adj[b].pb(i);
    }
    F0R(i, s){
        int a;
        cin >> a; --a;
        shop[a] = true;
    }
    vi depth(n), par(n);
    par[e] = -1;
    auto dfs = [&](auto self, int u, int p) -> void{
        trav(id, adj[u]){
            int v = edge[id][0] ^ u;
            if(v == p) continue;
            edge[id][2] = v;
            par[v] = id;
            depth[v] = depth[u] + 1;
            self(self, v, u);
        }
    };
    dfs(dfs, e, -1);

    vl dist(n);
    auto dfs_dist = [&](auto self, int u, int p, ll d) -> void{
        dbg(u, p, d)
        dist[u] = d;
        trav(id, adj[u]){
            int v = edge[id][0] ^ u;
            if(v == p) continue;
            self(self, v, u, d + edge[id][1]);
        }
    };
    dfs_dist(dfs_dist, e, -1, 0);

    vl mn(n);
    auto dfs_mn = [&](auto self, int u, int p) -> void{
        if(shop[u])
            mn[u] = dist[u];
        else mn[u] = 1e18;
        trav(id, adj[u]){
            int v = edge[id][0] ^ u;
            if(v == p) continue;
            self(self, v, u);
            mn[u] = min(mn[u], mn[v]);
        }
    };
    dfs_mn(dfs_mn, e, -1);

    F0R(i, n) if(mn[i] != 1e18)
        mn[i] -= 2 * dist[i];

    // vl cost_subtree(n, 1e18);
    // {
    //     priority_queue<array<ll, 3>> pq;
    //     F0R(i, n){
    //         if(shop[i]){
    //             pq.push({depth[i], 0, i});
    //             cost_subtree[i] = 0;
    //         }
    //     }
    //     while(!pq.empty()){
    //         auto [depth_, cost, u] = pq.top();
    //         pq.pop();
    //         cost *= -1;
    //         int id = par[u];
    //         if(id == -1)
    //             continue;
    //         int p = edge[id][0] ^ u;
    //         if(cost_subtree[p] > cost_subtree[u] + edge[id][1]){
    //             cost_subtree[p] = cost_subtree[u] + edge[id][1];
    //             pq.push({depth[p], -cost_subtree[p], p});
    //         }
    //     }
    // }
    int mxLog = 20;
    vector<vi> nxt(mxLog, vi(n));
    F0R(i, n) 
        if(par[i] == -1) nxt[0][i] = i;
        else nxt[0][i] = edge[par[i]][0] ^ i;
    FOR(k, 1, mxLog) F0R(i, n) 
        nxt[k][i] = nxt[k - 1][nxt[k - 1][i]];
        // if(nxt[k - 1][i] == -1) nxt[k][i] = -1;
        // else nxt[k][i] = nxt[k - 1][nxt[k - 1][i]];

    auto jump_k = [&](int i, int k){
        F0R(j, mxLog)
            if((k >> j) & 1){
                i = nxt[j][i];
                // if(i == -1) return -1;
            }
        return i;
    };

    vector<vl> nxt_mn(mxLog, vl(n, 1e18));
    dbg(par)
    F0R(i, n) nxt_mn[0][i] = mn[edge[(par[i] == -1 ? i : par[i])][0] ^ i];
    // F0R(i, n) nxt_mn[0][i] = mn[i];
    FOR(k, 1, mxLog) F0R(i, n){
        nxt_mn[k][i] = min(nxt_mn[k - 1][i], nxt_mn[k - 1][nxt[k - 1][i]]);
    }

    auto jump_mn = [&](int i, int k){
        ll x = mn[i];
        F0R(j, mxLog)
            if((k >> j) & 1){
                x = min(nxt_mn[j][i], x);
                i = nxt[j][i];
            }
        return x;
    };

    // vector<vl> nxt_mindist(mxLog, vl(n));
    // F0R(i, n) 
    //     if(par[i] == -1) nxt[0][i] = 1e18;
    //     else nxt[0][i] = edge[par[i]][1];
    // FOR(k, 1, mxLog) F0R(i, n)
    //     if(nxt[k][i] == -1) nxt_mindist[k][i] = 1e18;
    //     else nxt_mindist[k][i] = min(nxt_mindist[k - 1][nxt[k - 1][i]], nxt_mindist[k - 1][i]);


    // auto jump_k_cost = [&](int i, int k) -> ll{
    //     ll total_cost = 0;
    //     F0R(j, mxLog)
    //         if((k >> j) & 1){
    //             total_cost += nxt_dist[j][i];
    //             i = nxt[j][i];
    //             if(i == -1)
    //                 return 1e18;
    //         }
    //     return total_cost;
    // };
    dbg(dist)
    dbg(mn)
    dbg(shop)
    dbg(nxt)
    dbg(nxt_mn)

    while(q--){
        int id, x;
        cin >> id >> x; --id, --x;
        int y = edge[id][2];
        dbg(x, y)
        int diff = depth[x] - depth[y];
        dbg(diff)
        if(diff < 0 || (diff == 0 && x != y)){
            cout << "escaped" << nl;
            continue;
        }
        // if(x == y){
        //     if(cost_subtree[x] == 1e18)
        //         cout << "oo" << nl;
        //     else cout << cost_subtree[x] << nl;
        //     continue;
        // }
        int new_x = jump_k(x, diff);
        dbg(new_x, y)
        if(new_x != y){
            cout << "escaped" << nl;
            continue;
        }
        if(shop[x]){
            cout << 0 << nl;
            continue;
        }
        ll ans = jump_mn(x, diff);
        dbg(ans, x, diff)
        dbg(ans + dist[x])
        if(ans == 1e18){
            cout << "oo" << nl;
        }
        else{
            cout << ans + dist[x] << nl;
        }
        // if(cost_subtree[new_x] == 1e18){
        //     cout << "oo" << nl;
        //     continue;
        // }
        // ll ans = cost_subtree[new_x] + jump_k_cost(x, diff);
        // int lo = 0, hi = diff;
        // while(lo <= hi){
        //     int m = lo + (hi - lo) / 2;
        //     ll aux = cost_subtree[jump_k(x, m)] + jump_k_cost(x, m);
        //     if(aux <=)
        // }
    }
}
 
int32_t main(){
    ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    
    int TC = 1;
    // cin >> TC;
    while(TC--){
        solve();
    }
    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...