Submission #494278

#TimeUsernameProblemLanguageResultExecution timeMemory
494278wiwihoValley (BOI19_valley)C++14
0 / 100
989 ms92636 KiB
#include <bits/stdc++.h>
#include <bits/extc++.h>

#define StarBurstStream ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define iter(a) a.begin(), a.end()
#define riter(a) a.rbegin(), a.rend()
#define lsort(a) sort(iter(a))
#define gsort(a) sort(riter(a))
#define pb(a) push_back(a)
#define eb(a) emplace_back(a)
#define pf(a) push_front(a)
#define ef(a) emplace_front(a)
#define pob pop_back()
#define pof pop_front()
#define mp(a, b) make_pair(a, b)
#define F first
#define S second
#define mt make_tuple
#define gt(t, i) get<i>(t)
#define tomax(a, b) ((a) = max((a), (b)))
#define tomin(a, b) ((a) = min((a), (b)))
#define topos(a) ((a) = (((a) % MOD + MOD) % MOD))
#define uni(a) a.resize(unique(iter(a)) - a.begin())
#define printv(a, b) {bool pvaspace=false; \
for(auto pva : a){ \
    if(pvaspace) b << " "; pvaspace=true;\
    b << pva;\
}\
b << "\n";}

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

using pii = pair<int, int>;
using pll = pair<ll, ll>;
using pdd = pair<ld, ld>;
using tiii = tuple<int, int, int>;

const ll MOD = 1000000007;
const ll MAX = 2147483647;

template<typename A, typename B>
ostream& operator<<(ostream& o, pair<A, B> p){
    return o << '(' << p.F << ',' << p.S << ')';
}

ll ifloor(ll a, ll b){
    if(b < 0) a *= -1, b *= -1;
    if(a < 0) return (a - b + 1) / b;
    else return a / b;
}

ll iceil(ll a, ll b){
    if(b < 0) a *= -1, b *= -1;
    if(a > 0) return (a + b - 1) / b;
    else return a / b;
}

struct SegmentTree{
    vector<ll> st;
    int sz;
    void init(int _sz){
        sz = _sz;
        st.resize(sz * 4, MAX);
    }
    void modify(int x, int v, int L = -1, int R = -1, int id = 0){
        if(L == -1) L = 0;
        if(R == -1) R = sz - 1;
        //cerr << "modify " << x << " " << v << " " << L << " " << R << " " << sz << "\n";
        //assert(L <= R);
        if(L == R){
            st[id] = v;
            return;
        }
        int M = (L + R) / 2;
        if(x <= M) modify(x, v, L, M, 2 * id + 1);
        else modify(x, v, M + 1, R, 2 * id + 2);
        st[id] = min(st[2 * id + 1], st[2 * id + 2]);
    }
    ll query(int l, int r, int L = -1, int R = -1, int id = 0){
        if(l == -1) l = 0;
        if(r == -1) r = sz - 1;
        if(L == -1) L = 0;
        if(R == -1) R = sz - 1;
        if(l > r) return MAX;
        if(l <= L && R <= r) return st[id];
        int M = (L + R) / 2;
        if(r <= M) return query(l, r, L, M, 2 * id + 1);
        else if(l > M) return query(l, r, M + 1, R, 2 * id + 2);
        else return min(query(l, r, L, M, 2 * id + 1), query(l, r, M + 1, R, 2 * id + 2));
    }
};

int n;

vector<vector<pii>> g;
vector<bool> shop;
vector<vector<int>> pr, in, out;
vector<vector<ll>> dpt;
vector<SegmentTree> st;
vector<map<int, int>> sub;
vector<int> sz;
vector<bool> del;

vector<pii> e;
int esc;

void init(){
    g.resize(n + 1);
    shop.resize(n + 1);
    pr.resize(n + 1);
    in.resize(n + 1);
    out.resize(n + 1);
    dpt.resize(n + 1);
    st.resize(n + 1);
    sub.resize(n + 1);
    sz.resize(n + 1);
    del.resize(n + 1);

    e.resize(n);
}

void dfsg(int now, int p){
    sz[now] = 1;
    for(pii i : g[now]){
        if(i.F == p || del[i.F]) continue;
        dfsg(i.F, now);
        sz[now] += sz[i.F];
    }
}

int cen;
void dfsg2(int now, int p, int t){
    int mx = t - sz[now];
    for(pii i : g[now]){
        if(i.F == p || del[i.F]) continue;
        mx = max(mx, sz[i.F]);
        dfsg2(i.F, now, t);
    }
    if(mx <= t / 2) cen = now;
}

int ts;
void dfssub(int now, int p, ll d){
    sub[cen][now] = pr[now].size();
    in[now].eb(++ts);
    pr[now].eb(cen);
    dpt[now].eb(d);
    if(shop[now]){
        st[cen].modify(in[now].back(), d);
    }
    for(pii i : g[now]){
        if(i.F == p || del[i.F]) continue;
        dfssub(i.F, now, d + i.S);
    }
    out[now].eb(ts);
}

void solve(int rt){
    dfsg(rt, rt);
    dfsg2(rt, rt, sz[rt]);
    st[cen].init(sz[rt]);
    ts = -1;
    dfssub(cen, cen, 0);
    //cerr << "solve " << cen << "  ";
    //printv(sub[cen], cerr);
    
    del[cen] = true;
    for(pii i : g[cen]){
        if(!del[i.F]) solve(i.F);
    }
}

void query(int u1, int u2, int v){
    
    for(int i = (int)pr[v].size() - 1; i >= 0; i--){
        int cen = pr[v][i];
        if(sub[cen].find(esc) == sub[cen].end()) continue;
        
        if(sub[cen].find(u1) == sub[cen].end() || sub[cen].find(u2) == sub[cen].end()){
            cout << "escaped\n";
            return;
        }

        int id1 = sub[cen][u1];
        int id2 = sub[cen][u2];
        int ide = sub[cen][esc];
        if(in[u1][id1] > in[u2][id2]) swap(u1, u2), swap(id1, id2);
        //cerr << "escape " << v << " " << i << " " << cen << "\n";
        
        if((in[u2][id2] <= in[v][i] && out[v][i] <= out[u2][id2]) ||
                (in[u2][id2] <= in[esc][ide] && out[esc][ide] <= out[u2][id2])) break;

        cout << "escaped\n";
        return;
    }

    ll ans = MAX;
    for(int i = (int)pr[v].size() - 1; i >= 0; i--){
        int cen = pr[v][i];
        
        if(sub[cen].find(u1) == sub[cen].end() || sub[cen].find(u2) == sub[cen].end()){
            ans = min(ans, dpt[v][i] + st[cen].query(-1, -1));
            continue;
        }

        int id1 = sub[cen][u1];
        int id2 = sub[cen][u2];
        if(in[u1][id1] > in[u2][id2]) swap(u1, u2), swap(id1, id2);
        //cerr << "query " << v << " " << cen << " " << u1 << " " << u2 << "\n" 
        //        << in[u2][id2] << " " << st[cen].query(-1, in[u2][id2] - 1) << " " << out[u2][id2] << " " << st[cen].query(out[u2][id2] + 1, -1) << "\n";
        //for(int i = 0; i < st[cen].sz; i++) cerr << st[cen].query(i, i) << " ";
        //cerr << "\n";
        int ti = in[u2][id2], to = out[u2][id2];
        if(ti <= in[v][i] && out[v][i] <= to) break;
        ans = min({ans, dpt[v][i] + st[cen].query(-1, ti - 1), dpt[v][i] + st[cen].query(to + 1, -1)});
        break;
    }

    if(ans == MAX) cout << "oo\n";
    else cout << ans << "\n";
}

int main(){
    StarBurstStream

    int q, s;
    cin >> n >> s >> q >> esc;
    init();

    for(int i = 1; i < n; i++){
        int u, v, w;
        cin >> u >> v >> w;
        g[u].eb(mp(v, w));
        g[v].eb(mp(u, w));
        e[i] = mp(u, v);
    }

    for(int i = 0; i < s; i++){
        int c;
        cin >> c;
        shop[c] = true;
    }

    solve(1);

    //cerr << "test\n";
    /*for(int i = 1; i <= n; i++){
        cerr << i << "  ";
        printv(pr[i], cerr);
    }*/
    
    for(int i = 0; i < q; i++){
        int eid, v;
        cin >> eid >> v;
        int u1 = e[eid].F, u2 = e[eid].S;
        query(u1, u2, v);
    }

    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...