제출 #1088424

#제출 시각아이디문제언어결과실행 시간메모리
1088424PiokemonValley (BOI19_valley)C++17
100 / 100
112 ms40784 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

constexpr int N = 1e5;
constexpr int K = 17;
ll dst[N+9];
vector<pair<int,ll>> graf[N+9];
int par[N+9];
bool shop[N+9];
ll magic[N+9];
int jmppos[N+9][K+1];
ll jmpval[N+9][K+1];
int pre[N+9];
int post[N+9];
pair<int,int> kraw[N+9];
int tajm=1;

void dfs(int v){
    pre[v]=tajm++;
    for (pair<int,ll> x:graf[v]){
        if (x.first!=par[v]){
            dst[x.first]=dst[v]+x.second;
            par[x.first]=v;
            dfs(x.first);
        }
    }
    if (shop[v])magic[v]=dst[v];
    else magic[v]=(ll)1e17;
    for (pair<int,ll> x:graf[v]){
        if (x.first!=par[v]) magic[v]=min(magic[v],magic[x.first]);
    }
    post[v]=tajm++;
}

bool zawiera(int a,  int b){
    // czy w podrzewie a jest b;
    return (pre[a]<=pre[b]) && (post[b]<=post[a]);
}

ll minpath(int v, int kon){
    ll ans=1e17;
    for (int k=K;k>=0;k--){
        if (zawiera(kon,jmppos[v][k])){
            ans=min(ans,jmpval[v][k]);
            v=jmppos[v][k];
        }
    }
    ans=min(ans,magic[kon]);
    return ans;
}

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int n,s,q,e,a,b,w;
    cin >> n >> s >> q >> e;
    for (int x=1;x<n;x++){
        cin >> a >> b >> w;
        graf[a].push_back({b,w});
        graf[b].push_back({a,w});
        kraw[x]={a,b};
    }
    for (int x=1;x<=s;x++){
        cin >> a;
        shop[a]=1;
    }
    par[e]=e; dst[e]=0;
    dfs(e);
    for (int x=1;x<=n;x++)magic[x]-=2*dst[x];
    for (int x=1;x<=n;x++){
        jmpval[x][0]=magic[x];
        jmppos[x][0]=par[x];
    }
    for (int k=1;k<=K;k++){
        for (int x=1;x<=n;x++){
            jmppos[x][k]=jmppos[jmppos[x][k-1]][k-1];
            jmpval[x][k]=min(jmpval[x][k-1],jmpval[jmppos[x][k-1]][k-1]);
        }
    }
    while(q--){
        cin >> a >> b;
        if (zawiera(kraw[a].first,kraw[a].second))a=kraw[a].second;
        else a=kraw[a].first;
        if (!zawiera(a,b)){
            cout << "escaped\n";
            continue;
        }
        ll odp=minpath(b,a);
        odp += dst[b];
        if (odp>(ll)1e16)cout << "oo\n";
        else cout << odp << '\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...