이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define f first
#define s second
#define ll long long
const int MX = 1e5+5;
vector<pair<int, int>> adj[MX];
vector<pair<int, int>> edge(MX);
bool shop[MX];
ll subdist[MX];
ll dpdist[MX][20], tabdist[MX][20];
int parent[MX][20];
int sz[MX], st[MX], depth[MX];
int t, e;
void dfs(int curr, int par) {
//make sure everything counted
if(shop[curr]) subdist[curr] = 0LL;
++sz[curr];
st[curr] = t++;
for(auto &next : adj[curr]) if(next.f!=par) {
tabdist[next.f][0] = next.s*1LL;
parent[next.f][0] = curr;
depth[next.f] = depth[curr]+1;
dfs(next.f,curr);
subdist[curr] = min(subdist[curr], subdist[next.f]+next.s*1LL);
sz[curr]+=sz[next.f];
}
}
//check for overflow!
void query(int p, int r) {
//check if parent
if(st[r]<st[p] || st[r]>=st[p]+sz[p]) { //??
cout << "escaped" << "\n";
return;
}
ll ret = subdist[r];
ll distAdd = 0;
for(int bit=20;bit>=0;bit--) {
if(depth[r]-(1<<bit)>=depth[p]) {
ret = min(ret, distAdd+dpdist[r][bit]);
distAdd+=tabdist[r][bit];
r = parent[r][bit];
}
}
if(ret>=1e16) cout << "oo" << "\n";
else cout << ret << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
int n,s,q;
cin >> n >> s >> q >> e;
--e;
for(int i=0;i<n-1;i++) {
cin >> edge[i].f >> edge[i].s;
--edge[i].f, --edge[i].s;
int w; cin >> w;
adj[edge[i].f].push_back({edge[i].s,w});
adj[edge[i].s].push_back({edge[i].f,w});
}
for(int i=0;i<s;i++) {
int c; cin >> c;
shop[--c] = 1;
}
for(int i=0;i<n;i++) {
subdist[i] = 1e16;
for(int j=0;j<20;j++) tabdist[i][j] = 1e16;
}
dfs(e,-1);
for(int j=0;j<20;j++) {
for(int i=0;i<n;i++) {
if(j==0) {
dpdist[i][j] = min(tabdist[i][j]+subdist[parent[i][j]],subdist[i]);
}
else {
//check these
parent[i][j] = parent[ parent[i][j-1] ][j-1];
tabdist[i][j] = tabdist[i][j-1] + tabdist[ parent[i][j-1] ][j-1];
dpdist[i][j] = min(dpdist[i][j-1], tabdist[i][j-1]+dpdist[ parent[i][j-1] ][j-1]);
}
}
}
while(q--) {
int i,r; cin >> i >> r;
--i, --r;
int a = edge[i].f, b = edge[i].s;
if(depth[a]<depth[b]) swap(a,b);
query(a, r);
}
}
# | 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... |