이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
///***LTT***///
/// ->NHAT QUOC GIA<- ///
#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("popcnt")
#define int long long
#define endl "\n"
#define F first
#define S second
#define pb push_back
using namespace std;
const long long oo = 1e9+7;
const int N = 1e5 + 5;
int L[N], R[N], trace[N];
long long dis[N], tree[N * 4], lazy[N * 4];
int cnt[N];
queue <int> qu[N];
vector <pair <int, long long>> adj[N];
bool dd[N];
int l1[N], l2[N], r1[N], r2[N];
int n, e, s;
long long ans[N];
int q, a[N], b[N], w;
int tt = 0;
void build(int id,int l,int r){
if (l == r){
if (dd[trace[l]]) tree[id] = dis[trace[l]]; else tree[id] = 1e18;
return;
}
int mid = (l + r)/2;
build(id * 2, l, mid);
build(id * 2 + 1, mid + 1, r);
tree[id] = min(tree[id * 2], tree[id * 2 + 1]);
return;
}
void dfs1(int u,int p,long long d){
L[u] = ++tt;
dis[u] = d;
if (dd[u]) cnt[u]++;
trace[tt] = u;
for (auto x : adj[u]){
if (x.F != p){
dfs1(x.F, u, 1ll * d + x.S);
cnt[u] += cnt[x.F];
}
}
R[u] = tt;
return;
}
void down(int id,int l,int r){
if (l != r){
tree[id * 2] += lazy[id];
tree[id * 2 + 1] += lazy[id];
lazy[id * 2] += lazy[id];
lazy[id * 2 + 1] += lazy[id];
}
lazy[id] = 0;
return;
}
void update(int id,int l,int r,int u,int v,long long val){
if (lazy[id] != 0) down(id,l,r);
if (l > v or r < u) return;
if (l >= u and r <= v){
tree[id] += val;
lazy[id] += val;
return;
}
int mid = (l + r)/2;
update(id*2,l,mid,u,v,val);
update(id*2 + 1,mid + 1,r,u,v,val);
tree[id] = min(tree[id * 2], tree[id * 2 + 1]);
}
long long get(int id,int l,int r,int u,int v){
if (lazy[id] != 0) down(id,l,r);
if (l > v or r < u) return oo * oo;
if (l >= u and r <= v) return tree[id];
int mid = (l + r)/2;
return min(get(id * 2,l, mid,u ,v), get(id * 2 + 1,mid + 1, r, u, v));
}
void dfs(int u,int p, long long c){
update(1,1,n,L[u],R[u], -c);
if (L[u] - 1 != 0)
update(1,1,n,1,L[u] - 1, c);
if (R[u] + 1 <= n)
update(1,1,n,R[u] + 1, n, c);
while (!qu[u].empty()){
int tt = qu[u].front();
qu[u].pop();
if (l2[tt] == 0){
ans[tt] = get(1,1,n,l1[tt], r1[tt]);
} else {
long long v1 = get(1,1,n,l1[tt],r1[tt]);
long long v2 = oo * oo;
if (l2[tt] <= r2[tt]){
v2 = get(1,1,n,l2[tt], r2[tt]);
}
ans[tt] = min(v1, v2 );
}
}
for (auto x : adj[u]){
if (x.F != p){
dfs(x.F, u, x.S);
}
}
update(1,1,n,L[u],R[u], c);
if (L[u] - 1 != 0)
update(1,1,n,1,L[u] - 1, -c);
if (R[u] + 1 <= n)
update(1,1,n,R[u] + 1, n, -c);
return;
}
void inp(){
cin >> n >> s >> q >> e;
for (int i = 1;i < n;i++){
cin >> a[i] >> b[i] >> w;
adj[a[i]].pb({b[i],w});
adj[b[i]].pb({a[i],w});
}
return;
}
void solve(){
for (int i = 1;i <= s;i++){
int u;
cin >> u;
dd[u] = true;
}
dfs1(1,0, 0);
build(1,1,n);
int tt, r;
// cout << L[e] <<" "<< R[e] <<"\n";
for (int i = 1;i <= q;i++){
cin >> tt >> r;
int u = a[tt];
int v = b[tt];
if (L[u] > L[v]) swap(u,v);
if (L[r] >= L[v] and L[r] <= R[v]){
l1[i] = L[v];
r1[i] = R[v];
if (L[e] >= L[v] and L[e] <= R[v]){
ans[i] = -1;
continue;
}
if (cnt[v] == 0) ans[i] = -2; else qu[r].push(i);
} else {
l1[i] = 1;
r1[i] = L[v] - 1;
l2[i] = R[v] + 1;
r2[i] = n;
if (L[e] < L[v] or L[e] > R[v]){
ans[i] = -1;
continue;
}
if (cnt[1] - cnt[v] == 0) ans[i] = -2; else qu[r].push(i);
}
}
dfs(1,0, 0);
for (int i = 1;i <= q;i++){
if (ans[i] == -1){
cout <<"escaped\n";
continue;
}
if (ans[i] == -2){
cout << "oo\n";
continue;
}
cout << ans[i] <<"\n";
}
return;
}
signed main(){
ios_base::sync_with_stdio(NULL);
cin.tie(NULL);
cout.tie(NULL);
// if (fopen("file.inp", "r")){
// freopen("VALLEY.inp", "r", stdin);
// freopen("VALLEY.out", "w", stdout);
// }
//int t;
//cin >> t;
//while(t--){
inp();
solve();
//}
}
# | 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... |