# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
287287 | limabeans | Factories (JOI14_factories) | C++17 | 0 ms | 0 KiB |
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 "factories.h"
#include <bits/stdc++.h>
using namespace std;
template<typename T>
void out(T x) { cout << x << endl; exit(0); }
#define watch(x) cout << (#x) << " is " << (x) << endl
using ll = long long;
const ll inf = 1e18;
const ll mod = 1e9+7;
const int maxn = 1e6 + 5;
vector<pair<ll,int>> g[maxn];
const int LOG = 20;
int par[LOG+1][maxn];
ll wei[LOG+1][maxn];
int dep[maxn];
void dfs(int at, int p) {
if (~p) {
for (int j=1; j<LOG; j++) {
par[j][at] = par[j-1][par[j-1][at]];
wei[j][at] = wei[j-1][at] + wei[j-1][par[j-1][at]];
}
}
for (auto ed: g[at]) {
int to = ed.second;
if (to == p) continue;
par[0][to] = at;
wei[0][to] = ed.first;
dep[to] = 1+dep[at];
dfs(to, at);
}
}
int lca(int u, int v) {
if (dep[u]<dep[v]) swap(u, v);
int dx = dep[u]-dep[v];
for (int j=0; j<LOG; j++) {
if (dx>>j&1) {
u=par[j][u];
}
}
if (u==v) return v;
for (int j=LOG-1; j>=0; j--) {
if (par[j][u] != par[j][v]) {
u=par[j][u];
v=par[j][v];
}
}
return par[0][v];
}
ll walk(ll at, ll to) {
if (at==to) return 0;
assert(dep[at]>dep[to]);
ll res = 0;
for (int j=LOG-1; j>=0 && at!=to; j--) {
int up = par[j][at];
if (dep[up]>=dep[to]) {
res += wei[j][at];
at=up;
}
}
return res;
}
ll dist(int u, int v) {
if (u==v) return 0;
int mid = lca(u,v);
return walk(u,mid)+walk(v,mid);
}
void Init(int N, int A[], int B[], int D[]) {
for (int i=0; i<N; i++) {
g[A[i]].push_back({D[i],B[i]});
g[B[i]].push_back({D[i],A[i]});
}
dfs(0, -1);
}
long long Query(int S, int X[], int T, int Y[]) {
ll res = inf;
for (int i=0; i<S; i++) {
for (int j=0; j<T; j++) {
//cout<<X[i]<<","<<Y[j]<<endl;
res = min(res, dist(X[i],Y[j]));
}
}
return res;
}
int n, q;
int a[maxn], b[maxn], d[maxn];
int x[maxn], y[maxn];
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n>>q;
for (int i=0; i<n-1; i++) {
cin>>a[i]>>b[i]>>d[i];
}
Init(n,a,b,d);
// assert(dist(1,2)==4);
// assert(dist(0,3)==13);
// assert(dist(2,6)==7);
// assert(dist(5,0)==19);
// assert(dist(5,6)==18);
for (int i=0; i<q; i++) {
int s, t;
cin>>s>>t;
for (int j=0; j<s; j++) {
cin>>x[j];
}
for (int j=0; j<t; j++) {
cin>>y[j];
}
cout<<Query(s,x,t,y)<<endl;
}
return 0;
}