This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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 = 1LL << 60;
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;
}
int n;
struct SegmentTree{
vector<ll> st;
int sz;
explicit SegmentTree(int sz): sz(sz){
st.resize(4 * sz, MAX);
}
void modify(int x, ll v, int L = 1, int R = n, int id = 0){
//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 = n, int id = 0){
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));
}
};
vector<vector<pii>> g;
vector<bool> shop;
vector<vector<int>> pr, in, out;
vector<vector<ll>> dpt;
vector<SegmentTree> st;
vector<int> sz, ts;
vector<bool> del;
const int SZ = 20;
vector<pii> e;
int esc;
void init(){
g.resize(n + 1);
shop.resize(n + 1);
pr.resize(SZ, vector<int>(n + 1, -1));
in.resize(SZ, vector<int>(n + 1, -1));
out.resize(SZ, vector<int>(n + 1, -1));
dpt.resize(SZ, vector<ll>(n + 1));
st.resize(SZ, SegmentTree(n));
sz.resize(n + 1);
del.resize(n + 1);
ts.resize(SZ);
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;
}
void dfssub(int now, int p, ll d, int gd){
in[gd][now] = ++ts[gd];
pr[gd][now] = cen;
dpt[gd][now] = d;
if(shop[now]){
st[gd].modify(in[gd][now], d, 1, n, 0);
}
for(pii i : g[now]){
if(i.F == p || del[i.F]) continue;
dfssub(i.F, now, d + i.S, gd);
}
out[gd][now] = ts[gd];
}
void solve(int rt, int gd){
dfsg(rt, rt);
dfsg2(rt, rt, sz[rt]);
dfssub(cen, cen, 0, gd);
//cerr << "solve " << cen << " ";
//printv(sub[cen], cerr);
del[cen] = true;
for(pii i : g[cen]){
if(!del[i.F]) solve(i.F, gd + 1);
}
}
ll oao = MAX;
void query(int u1, int u2, int v){
for(int i = SZ - 1; i >= 0; i--){
if(pr[i][v] == -1 || pr[i][esc] == -1) continue;
if(pr[i][v] != pr[i][esc]) continue;
int cen = pr[i][v];
if(pr[i][u1] != cen || pr[i][u2] != cen){
cout << "escaped\n";
return;
}
if(in[i][u1] > in[i][u2]) swap(u1, u2);
if(in[i][u2] <= in[i][v] && out[i][v] <= out[i][u2]) break;
if(in[i][u2] <= in[i][esc] && out[i][esc] <= out[i][u2]) break;
cout << "escaped\n";
return;
}
ll ans = MAX;
for(int i = SZ - 1; i >= 0; i--){
if(pr[i][v] == -1) continue;
int cen = pr[i][v];
if(pr[i][u1] != cen || pr[i][u2] != cen){
ans = min(ans, dpt[i][v] + st[i].query(in[i][cen], out[i][cen]));
//cerr << "query " << i << " " << v << " " << "\n";
//for(int j = in[i][cen]; j <= out[i][cen]; j++) cerr << st[i].query(j, j) << " ";
//cerr << "\n";
continue;
}
if(in[i][u1] > in[i][u2]) swap(u1, u2);
if(in[i][u2] <= in[i][v] && out[i][v] <= out[i][u2]) continue;
ans = min(ans, dpt[i][v] + st[i].query(in[i][cen], in[i][u2] - 1));
ans = min(ans, dpt[i][v] + st[i].query(out[i][u2] + 1, out[i][cen]));
/*if(in[i][v] <= in[i][u2] && out[i][u2] <= out[i][v]){
ans = min(ans, dpt[i][v] + st[i].query(in[i][cen], in[i][v] - 1));
ans = min(ans, dpt[i][v] + st[i].query(out[i][v] + 1, out[i][cen]));
}
else if(in[i][u2] <= in[i][v]){
ans = min(ans, dpt[i][v] + st[i].query(in[i][cen], in[i][u2] - 1));
ans = min(ans, dpt[i][v] + st[i].query(out[i][u2] + 1, in[i][v] - 1));
ans = min(ans, dpt[i][v] + st[i].query(out[i][v] + 1, out[i][cen]));
}
else{
ans = min(ans, dpt[i][v] + st[i].query(in[i][cen], in[i][v] - 1));
ans = min(ans, dpt[i][v] + st[i].query(out[i][v] + 1, in[i][u2] - 1));
ans = min(ans, dpt[i][v] + st[i].query(out[i][u2] + 1, out[i][cen]));
}*/
}
//if(ans != oao) cerr << ans << " " << oao << "\n";
//assert(ans == oao);
if(ans == MAX) cout << "oo\n";
else cout << ans << "\n";
//if(oao == MAX) cout << "oo\n";
//else cout << oao << "\n";
}
void dfsbf(int now, int p, int u1, int u2, ll d){
if(now == esc) oao = -1;
if(shop[now]) oao = min(oao, d);
for(pii i : g[now]){
if(i.F == p) continue;
if(mp(now, i.F) == mp(u1, u2) || mp(now, i.F) == mp(u2, u1)) continue;
dfsbf(i.F, now, u1, u2, d + i.S);
}
}
int N = 20;
mt19937 rnd(2124123);
uniform_int_distribution<int> ud(1, 1000000000);
uniform_int_distribution<int> ud2(1, N);
int main(){
StarBurstStream
int q, s;
cin >> n >> s >> q >> esc;
//n = N;
//s = 1;
//q = N;
//esc = ud2(rnd);
init();
for(int i = 1; i < n; i++){
int u, v, w;
cin >> u >> v >> w;
//u = i; v = i + 1;
//w = ud(rnd);
g[u].eb(mp(v, w));
g[v].eb(mp(u, w));
e[i] = mp(u, v);
//cerr << u << " " << v << " " << w << "\n";
}
for(int i = 0; i < s; i++){
int c;
cin >> c;
//c = ud2(rnd);
shop[c] = true;
//cerr << "shop " << c << "\n";
}
solve(1, 0);
/*cerr << "pr\n";
for(int i = 0; i < SZ; i++){
printv(pr[i], cerr);
}
cerr << "in\n";
for(int i = 0; i < SZ; i++){
printv(in[i], cerr);
}
cerr << "out\n";
for(int i = 0; i < SZ; i++){
printv(out[i], cerr);
}*/
for(int i = 0; i < q; i++){
int eid, v;
cin >> eid >> v;
//eid = ud2(rnd); if(eid == n) eid--;
//v = ud2(rnd);
int u1 = e[eid].F, u2 = e[eid].S;
//cerr << eid << " " << v << "\n";
//oao = MAX;
//dfsbf(v, v, u1, u2, 0);
query(u1, u2, v);
}
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |