이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T> void check_min(T &a, const T &b){ a = (a < b) ? a : b; }
template<class T> void check_max(T &a, const T &b){ a = (a > b) ? a : b; }
#define all(x) (x).begin(), (x).end()
const ll INF = 1e18;
const ll N = 1e5 + 3;
const ll MX = 1e15;
const int LOGN = 20;
int n, s, q, e;
vector<pair<int, ll>> adj[N];
bool shop[N];
int d[N], par[N];
ll up[LOGN][N], min_up[LOGN][N], mdist[N];
ll droot[N];
int lca(int u, int v){
if(d[u] != d[v]){
if(d[u] < d[v])
swap(u, v);
int diff = d[u] - d[v];
for(int i = LOGN - 1; i >= 0; --i){
if(diff >> i & 1){
u = par[up[i][u]];
}
}
}
if(u == v)
return u;
for(int i = LOGN - 1; i >= 0; --i){
if(par[up[i][u]] != par[up[i][v]]){
u = par[up[i][u]];
v = par[up[i][v]];
}
}
return par[u];
}
void init_up(){
for(int i = 1; i <= n; ++i){
up[0][i] = i;
min_up[0][i] = mdist[i] - droot[i];
}
for(int j = 1; j < LOGN; ++j){
for(int i = 1; i <= n; ++i){
up[j][i] = up[j - 1][par[up[j - 1][i]]];
min_up[j][i] = min(min_up[j - 1][i], min_up[j - 1][par[up[j - 1][i]]]);
}
}
}
void dfs(int u, int p){
par[u] = p;
mdist[u] = shop[u] ? 0 : INF;
for(auto [to, w]: adj[u]){
if(to == p)
continue;
d[to] = d[u] + 1;
droot[to] = droot[u] + w;
dfs(to, u);
check_min(mdist[u], mdist[to] + w);
}
}
array<int, 3> edges[N];
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> s >> q >> e;
for(int i = 0; i < n - 1; ++i){
int u, v, w;
cin >> u >> v >> w;
adj[u].push_back({v, w});
adj[v].push_back({u, w});
edges[i + 1] = {u, v, w};
}
for(int i = 0; i < s; ++i){
int c;
cin >> c;
shop[c] = true;
}
dfs(e, e);
init_up();
for(int i = 1; i <= n - 1; ++i){
if(d[edges[i][0]] < d[edges[i][1]])
swap(edges[i][0], edges[i][1]);
}
for(int i = 0; i < q; ++i){
int idx, r;
cin >> idx >> r;
if(lca(edges[idx][0], r) != edges[idx][0]){
cout << "escaped\n";
continue;
}
ll ans = INF;
int target_d = d[edges[idx][0]];
int curr_d = d[r];
int num_nodes = curr_d - target_d + 1;
int cd = r;
for(int i = LOGN - 1; i >= 0; --i)
if(num_nodes >> i & 1){
check_min(ans, droot[r] + min_up[i][cd]);
cd = par[up[i][cd]];
}
if(ans >= MX){
cout << "oo\n";
}
else{
cout << ans << "\n";
}
}
}
# | 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... |