이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define ll long long
const int l = 21;
const ll inf = 2e15;
const int MAX_N = 5e5 + 15;
int n, m, sz[MAX_N], up[MAX_N][l], tin[MAX_N], tout[MAX_N], last;
ll minn[MAX_N];
vector <int> g[MAX_N], d[MAX_N];
int pCentroid[MAX_N];
ll dist[MAX_N];
bool deleted[MAX_N];
void start(int v, int p) {
tin[v] = ++last;
up[v][0] = p;
for(int i = 1; i < l; ++i)
up[v][i] = up[up[v][i-1]][i-1];
for(int i = 0; i < g[v].size(); ++i)
if(g[v][i] != p) {
dist[g[v][i]] = dist[v] + d[v][i];
start(g[v][i], v);
}
tout[v] = ++last;
}
inline bool upper(int a, int b) {
return tin[a] <= tin[b] && tout[a] >= tout[b];
}
int lca(int a, int b) {
if(upper(a, b))
return a;
if(upper(b, a))
return b;
for(int i = l - 1; i >= 0; --i)
if(!upper(up[a][i], b))
a = up[a][i];
return up[a][0];
}
void build(int v, int p = -1) {
sz[v] = 1;
for(auto to : g[v])
if(to != p && !deleted[to]) {
build(to, v);
sz[v] += sz[to];
}
}
int centroid(int v, int p, int n) {
for(auto to : g[v])
if(!deleted[to] && to != p && sz[to] > n / 2)
return centroid(to, v, n);
return v;
}
void process(int node, int p = -1) {
build(node, -1);
int center = centroid(node, node, sz[node]);
deleted[center] = true;
if(p == -1)
p = center;
pCentroid[center] = p;
for(int to : g[center])
if(!deleted[to])
process(to, center);
}
inline ll distance(int u, int v) {
return dist[u] + dist[v] - 2 * dist[lca(u, v)];
}
void Init(int N, int A[], int B[], int D[]) {
n = N;
for(int i = 0; i < n; ++i) {
++A[i];
++B[i];
g[A[i]].pb(B[i]);
d[A[i]].pb(D[i]);
g[B[i]].pb(A[i]);
d[B[i]].pb(D[i]);
}
fill(minn, minn + MAX_N, inf);
start(1, 1);
process(1);
}
long long Query(int S, int X[], int T, int Y[]) {
ll ans = inf;
for(int i = 0; i < S; ++i)
++X[i];
for(int i = 0; i < T; ++i)
++Y[i];
for(int i = 0; i < S; ++i) {
int v = X[i];
while(1) {
minn[v] = min(minn[v], distance(v, X[i]));
if(v == pCentroid[v])
break;
v = pCentroid[v];
}
}
for(int i = 0; i < T; ++i) {
int v = Y[i];
while(1) {
ans = min(ans, distance(v, Y[i]) + minn[v]);
if(v == pCentroid[v])
break;
v = pCentroid[v];
}
}
for(int i = 0; i < S; ++i) {
int v = X[i];
while(1) {
minn[v] = inf;
if(v == pCentroid[v])
break;
v = pCentroid[v];
}
}
return ans;
}
컴파일 시 표준 에러 (stderr) 메시지
factories.cpp: In function 'void start(int, int)':
factories.cpp:24:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for(int i = 0; i < g[v].size(); ++i)
~~^~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |