Submission #1091227

#TimeUsernameProblemLanguageResultExecution timeMemory
1091227MrPavlitoValley (BOI19_valley)C++17
100 / 100
148 ms52308 KiB
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define sc second
#define endl "\n"
#define pii pair<int,int>

using namespace std;

const int MAXN = 1e5+5;
const int mod7 = 1e9+7;
const long long inf = 1e18;
const int lg = 18;

vector<vector<pii>> graf(MAXN);
int n,s,q,e;
int t = 1;
int up[MAXN][lg];
int mnup[MAXN][lg];
int tin[MAXN];
int tout[MAXN];
int nmofshops[MAXN];
int dist[MAXN];
int shopdist[MAXN];
int parents[MAXN];
bool isshop[MAXN];

void dfs(int nod, int p, int d)
{
    tin[nod] = t++;
    parents[nod] = p;
    nmofshops[nod]+= isshop[nod];
    up[nod][0] = p;
    dist[nod] = d;
    if(isshop[nod])shopdist[nod] = d;
    else shopdist[nod] = inf;
    for(auto x: graf[nod])
    {
        if(x.fi == p) continue;
        dfs(x.fi, nod, d+x.sc);
        nmofshops[nod] += nmofshops[x.fi];
    }
    for(auto x:graf[nod])if(x.fi!=p)shopdist[nod] = min(shopdist[x.fi], shopdist[nod]);
    tout[nod] = t++;
}

void fillUp()
{
    for(int i=1; i<lg; i++)
    {
        for(int j=1; j<=n; j++)
        {
            up[j][i] = up[up[j][i-1]][i-1];
            mnup[j][i] = min(mnup[j][i-1], mnup[up[j][i-1]][i-1]);
        }
    }
}

int lca(int u, int v)
{
    if(u == v)return u;
    if(tin[u] < tin[v] && tout[u] > tout[v])return u;
    if(tin[v] < tin[u] && tout[v] > tout[u])return v;

    for(int i = lg-1; i>=0; i--)
    {
        int parentcheck = up[v][i];
        if(!(tin[parentcheck] < tin[u] && tout[parentcheck]> tout[u]))v = parentcheck;
    }
    return up[v][0];
}

bool canEscape(int u1, int u2, int x)
{
    if(dist[u1] > dist[u2])swap(u1,u2);
    if(lca(u2, x) == u2)return false;
    return true;
}

bool canReachshop(int u1, int u2)
{
    if(dist[u1] > dist[u2])swap(u1,u2);
    return nmofshops[u2];
}

int calc(int u1, int u2, int x)
{
    if(dist[u1] > dist[u2])swap(u1,u2);
    if(isshop[x])return 0;
    int rez = dist[x];
    int mn = shopdist[x];
    for(int i=lg-1; i>=0; i--)
    {
        int parentcheck = up[x][i];
        if(tin[parentcheck] >= tin[u2] && tout[parentcheck]<= tout[u2])
        {
            mn = min(mn, mnup[x][i]);
            x = parentcheck;
        }
    }
    return rez+mn;

}


struct grana{int a,b,c;};
signed main()
{
    ios_base::sync_with_stdio(false),cin.tie(0), cout.tie(0);
    int tt=1;
    //cin >> tt;
    while(tt--)
    {
        cin >> n >> s >> q >> e;
        vector<int> prodavnice(s);
        vector<grana> svegrane(n-1);
        for(int i=0; i<n-1; i++)
        {
            int a,b,c;cin >> a >> b >> c;
            graf[a].pb({b,c});
            graf[b].pb({a,c});
            svegrane[i] = {a,b,c};
        }
        for(int i=0; i<s; i++)
        {
            cin >> prodavnice[i];
            isshop[prodavnice[i]] = 1;
        }
        dfs(e,e,0);
        for(int i=1; i<=n; i++)shopdist[i]-= 2*dist[i];
        //for(int i=1; i<=n; i++)cout << shopdist[i] << " ";cout << endl;
        for(int i=1; i<=n; i++)mnup[i][0] = shopdist[parents[i]];
        fillUp();
        while(q--)
        {
            int a, b;
            cin >> a >> b;
            a--;
            int u1 = svegrane[a].a;
            int u2 = svegrane[a].b;
            if(canEscape(u1,u2, b))cout << "escaped" << endl;
            else if(!canReachshop(u1,u2))cout << "oo" << endl;
            else cout << calc(u1,u2,b) << endl;
        }
    }
}
/*
 5 2 3 1
 1 2 3
 1 3 2
 3 4 1
 3 5 2
 2
 4
 2 2
 2 5
 4 5
 */

 /*
10 2 5 4
 7 2 3
 4 8 3
 9 10 1
 6 7 3
 9 2 3
 10 1 2
 8 2 2
 5 2 1
 3 8 2
 8
 7
 2 1
 1 5
 8 4
 6 2
 7 7
 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...