Submission #1290129

#TimeUsernameProblemLanguageResultExecution timeMemory
1290129MinbaevValley (BOI19_valley)C++20
23 / 100
195 ms69232 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

//#pragma GCC target("avx,avx2,fma")
//#pragma GCC optimize("Ofast,unroll-loops")

using namespace std;
using namespace __gnu_pbds;

#define pb      push_back
#define all(x)  x.begin(),x.end()
#define int     long long
// #define double  long double
#define ar      array
#define mrand(a, b)   uniform_int_distribution<int>(a, b)(rng)

template<class T>bool umax(T &a,T b){if(a<b){a=b;return true;}return false;}
template<class T>bool umin(T &a,T b){if(b<a){a=b;return true;}return false;}

template<class T> using ste = tree<T, null_type, less_equal<T>,
rb_tree_tag, tree_order_statistics_node_update>;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

int binpow(int a, int b, int m){
    if(b <= 0)return 1; 	
    if(b % 2 == 0){
        int c = binpow(a,b/2,m);
        return (c*c)%m;
    }
    return (binpow(a,b-1,m)*a)%m;
}

int divi(int a, int b, int m){
    return (a*(binpow(b,m-2, m)))%m;
}

struct modint {
    static int mod;
    long long val;

    modint(long long v = 0) {
        val = v % mod;
        if (val < 0) val += mod;
    }

    modint& operator+=(const modint& other) {
        val += other.val;
        if (val >= mod) val -= mod;
        return *this;
    }
    modint& operator+=(long long other) {
        return *this += modint(other);
    }

    modint& operator-=(const modint& other) {
        val -= other.val;
        if (val < 0) val += mod;
        return *this;
    }
    modint& operator-=(long long other) {
        return *this -= modint(other);
    }

    modint& operator*=(const modint& other) {
        val = (val * other.val) % mod;
        return *this;
    }
    modint& operator*=(long long other) {
        return *this *= modint(other);
    }

    modint& operator/=(const modint& other) {
        val = divi(val, other.val, mod);
        return *this;
    }
    modint& operator/=(long long other) {
        return *this /= modint(other);
    }

    friend modint operator+(modint a, const modint& b) { return a += b; }
    friend modint operator+(modint a, long long b) { return a += b; }
    friend modint operator+(long long a, modint b) { return b += a; }

    friend modint operator-(modint a, const modint& b) { return a -= b; }
    friend modint operator-(modint a, long long b) { return a -= b; }
    friend modint operator-(long long a, modint b) { return modint(a) -= b; }

    friend modint operator*(modint a, const modint& b) { return a *= b; }
    friend modint operator*(modint a, long long b) { return a *= b; }
    friend modint operator*(long long a, modint b) { return b *= a; }

    friend modint operator/(modint a, const modint& b) { return a /= b; }
    friend modint operator/(modint a, long long b) { return a /= b; }
    friend modint operator/(long long a, modint b) { return modint(a) /= b; }

    friend ostream& operator<<(ostream& os, const modint& m) {
        return os << m.val;
    }
};

int modint::mod = 1e9 + 7;

namespace FAST {
    template<typename T>
    istream &operator>>(istream &cin, vector<T> &a) {
    for (T &i: a) cin >> i;
        return cin;
    }

    template<typename T>
    ostream &operator<<(ostream &cout, vector<T> &a) {
          for (T i: a) cout << i << ' ';
        return cout;
    }
}
using namespace FAST;

const int inf = 3e18 + 7;
const int mod = 1e9 + 7;
const int N = 6e5 + 5;
const int md = 998244353;

int rev(int a, int m){
	if (a == 1)return 1;
	return (1 - rev(m % a, a) * m) / a + m;
}

struct Bit {
    vector<int> b, b2;
    int n;

    Bit(int n) {
        this->n = n + 1;
        b.assign(n + 1, 0);
        b2.assign(n+1, 0);
    }

    void add(vector<int>&b, int idx, int x){
        while(idx <= n){
            b[idx] += x;
            idx += idx & -idx;
        }
    }

    void upd(int l, int r, int x){
        add(b, l, x);
        add(b, r+1, -x);
        add(b2, l, x*(l-1));
        add(b2, r+1, -x*r);
    }

    int sum(vector<int>&b, int idx){
        int res = 0;
        while(idx > 0){
            res += b[idx];
            idx -= idx & -idx;
        }
        return res;
    }

    int pref(int idx){
        return sum(b, idx) * idx - sum(b2, idx);
    }

    int get(int l, int r){                  
        return pref(r) - pref(l-1);
    }
};

int n,m,k;
vector<int>tin(N), tout(N), dep(N), dp(N), type(N);
vector<ar<int,2>>g[N];
int p[N][20], val[N][20];
int timer;

int dfs(int x, int pr){
	tin[x] = ++timer;
	p[x][0] = pr;
	for(int i = 1;i<20;i++)
		p[x][i] = p[p[x][i-1]][i-1];
	
	int mn = inf;
	for(auto [to, cost] : g[x]){
		if(to == pr)continue;
		dep[to] = dep[x] + cost; 
		umin(mn, dfs(to, x));
	}
	
	if(type[x])umin(mn, dep[x]);
	dp[x] = mn - 2 * dep[x];
	
	tout[x] = ++timer;
	return mn;
}

void dfs2(int x, int pr){
	val[x][0] = min(dp[x], dp[pr]);
	for(int i = 1;i<20;i++)
		val[x][i] = min(val[x][i-1], val[p[x][i-1]][i-1]);
	
	for(auto [to, cost] : g[x]){
		if(to == pr)continue;
		dfs2(to, x);
	}
}

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

int lca(int a, int b){
	int mn = dp[a];
	if(a == b)return mn;
	
	for(int i = 19;i>=0;i--){
		if(!is(p[a][i], b)){
			umin(mn, val[a][i]);
			a = p[a][i];
		}
	}
	
	return min(mn, val[a][0]);
}

void solve(){

	int q;
	cin >> n >> m >> q >> k;
	
	vector<ar<int,2>>vs;
	for(int i = 2;i<=n;i++){
		int a,b,c;
		cin >> a >> b >> c;
		g[a].pb({b, c});
		g[b].pb({a, c});
		vs.pb({a, b});
	}
	
	for(int i = 1;i<=m;++i){
		int a;
		cin >> a;
		type[a] = 1;
	}
	
	dfs(k, k);
	dfs2(k, k);
	
	//~ for(int i = 1;i<=n;i++){
		//~ cout << dp[i] << " ";
	//~ }
	//~ cout << "\n";
	
	while(q--){
		int a,b;
		cin >> a >> b;
		a -= 1;
		if(dep[vs[a][0]] >= dep[vs[a][1]])a = vs[a][0];
		else a = vs[a][1];
	
		//~ cout << a << " " << b << "\n";
		//~ continue;
		
		if(!is(a, b)){
			cout << "escaped\n";
			continue;
		}
		
		int ans = lca(b, a);
		if(ans + dep[b] <= n-1){
			cout << ans + dep[b] << "\n";
		}
		else cout << "oo\n";
	}
	
	
	
}
/*
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
*/
 signed main()
{
//  freopen("seq.in", "r", stdin);
//  freopen("seq.out", "w", stdout);
    ios_base::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL);
    int tt=1;//cin >> tt;
    while(tt--)solve();	

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...