이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define sc second
#define endl "\n"
#define pii pair<int,int>
using namespace std;
const int MAXN = 1e5+5;
const int mod7 = 1e9+7;
const long long inf = 1e18;
const int lg = 18;
vector<vector<pii>> graf(MAXN);
int n,s,q,e;
int t = 1;
int up[MAXN][lg];
int mnup[MAXN][lg];
int tin[MAXN];
int tout[MAXN];
int nmofshops[MAXN];
int dist[MAXN];
int shopdist[MAXN];
int parents[MAXN];
bool isshop[MAXN];
void dfs(int nod, int p, int d)
{
tin[nod] = t++;
parents[nod] = p;
nmofshops[nod]+= isshop[nod];
up[nod][0] = p;
dist[nod] = d;
if(isshop[nod])shopdist[nod] = d;
else shopdist[nod] = inf;
for(auto x: graf[nod])
{
if(x.fi == p) continue;
dfs(x.fi, nod, d+x.sc);
nmofshops[nod] += nmofshops[x.fi];
}
for(auto x:graf[nod])if(x.fi!=p)shopdist[nod] = min(shopdist[x.fi], shopdist[nod]);
tout[nod] = t++;
}
void fillUp()
{
for(int i=1; i<lg; i++)
{
for(int j=1; j<=n; j++)
{
up[j][i] = up[up[j][i-1]][i-1];
mnup[j][i] = min(mnup[j][i-1], mnup[up[j][i-1]][i-1]);
}
}
}
int lca(int u, int v)
{
if(u == v)return u;
if(tin[u] < tin[v] && tout[u] > tout[v])return u;
if(tin[v] < tin[u] && tout[v] > tout[u])return v;
for(int i = lg-1; i>=0; i--)
{
int parentcheck = up[v][i];
if(!(tin[parentcheck] < tin[u] && tout[parentcheck]> tout[u]))v = parentcheck;
}
return up[v][0];
}
bool canEscape(int u1, int u2, int x)
{
if(dist[u1] > dist[u2])swap(u1,u2);
if(lca(u2, x) == u2)return false;
return true;
}
bool canReachshop(int u1, int u2)
{
if(dist[u1] > dist[u2])swap(u1,u2);
return nmofshops[u2];
}
int calc(int u1, int u2, int x)
{
if(dist[u1] > dist[u2])swap(u1,u2);
if(isshop[x])return 0;
int rez = dist[x];
int mn = inf;
for(int i=lg-1; i>=0; i--)
{
int parentcheck = up[x][i];
if(tin[parentcheck] >= tin[u2] && tout[parentcheck]<= tout[u2])
{
mn = min(mn, mnup[x][i]);
x = parentcheck;
}
}
return min(rez+mn, shopdist[x]);
}
struct grana{int a,b,c;};
signed main()
{
ios_base::sync_with_stdio(false),cin.tie(0), cout.tie(0);
int tt=1;
//cin >> tt;
while(tt--)
{
cin >> n >> s >> q >> e;
vector<int> prodavnice(s);
vector<grana> svegrane(n-1);
for(int i=0; i<n-1; i++)
{
int a,b,c;cin >> a >> b >> c;
graf[a].pb({b,c});
graf[b].pb({a,c});
svegrane[i] = {a,b,c};
}
for(int i=0; i<s; i++)
{
cin >> prodavnice[i];
isshop[prodavnice[i]] = 1;
}
dfs(e,e,0);
for(int i=1; i<=n; i++)shopdist[i]-= 2*dist[i];
//for(int i=1; i<=n; i++)cout << shopdist[i] << " ";cout << endl;
for(int i=1; i<=n; i++)mnup[i][0] = shopdist[parents[i]];
fillUp();
while(q--)
{
int a, b;
cin >> a >> b;
a--;
int u1 = svegrane[a].a;
int u2 = svegrane[a].b;
if(canEscape(u1,u2, b))cout << "escaped" << endl;
else if(!canReachshop(u1,u2))cout << "oo" << endl;
else cout << calc(u1,u2,b) << endl;
}
}
}
/*
5 2 3 1
1 2 3
1 3 2
3 4 1
3 5 2
2
4
2 2
2 5
4 5
*/
/*
10 2 5 4
7 2 3
4 8 3
9 10 1
6 7 3
9 2 3
10 1 2
8 2 2
5 2 1
3 8 2
8
7
2 1
1 5
8 4
6 2
7 7
*/
# | 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... |