이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
#include "factories.h"
const int MAX = 6e5;
const long long OO = 0x3f3f3f3f3f3f3f3f;
#define ii pair<int, int>
#define f first
#define s second
int n, max_log;
vector<ii> G[MAX];
int anc[MAX][22], depth[MAX];
int CD[MAX], sz[MAX];
bool cut[MAX];
long long ans[MAX], weight[MAX];
void dfs(int v, int p, int d)
{
anc[v][0] = p;
depth[v] = d;
if(d) max_log = max(max_log, (int)log2(d));
for(auto [u, w] : G[v]) {
if(u != p) {
weight[u] = weight[v] + w;
dfs(u, v, d + 1);
}
}
}
void build()
{
memset(anc, -1, sizeof(anc));
dfs(0, -1, 0);
for(int j = 1; j <= max_log; j++)
for(int i = 0; i < n; i++)
if(anc[i][j-1] != -1)
anc[i][j] = anc[anc[i][j-1]][j-1];
}
int walk(int v, int k)
{
while(k)
v = anc[v][(int)(log2(k & -k))], k -= (k&-k);
return v;
}
int lca(int u, int v)
{
if(depth[u] > depth[v]) u = walk(u, depth[u] - depth[v]);
if(depth[u] < depth[v]) v = walk(v, depth[v] - depth[u]);
if(u == v) return u;
for(int i = max_log; i >= 0; i--)
if(anc[u][i] != anc[v][i])
{
u = anc[u][i];
v = anc[v][i];
}
return anc[u][0];
}
int dfs2(int v, int p)
{
int s = 1;
for(auto [u, w] : G[v])
if(!cut[u] and u != p)
s += dfs2(u, v);
return sz[v] = s;
}
int find_centroid(int v, int p, int tot)
{
int next_v, cnt = 0;
for(auto [u, w] : G[v])
if(!cut[u] and u != p and sz[u] > cnt)
cnt = sz[u], next_v = u;
if(cnt > tot / 2) return find_centroid(next_v, v, tot);
return v;
}
void build_centroid_tree(int v, int p)
{
dfs2(v, -1);
int u = find_centroid(v, -1, sz[v]);
CD[u] = p;
cut[u] = true;
for(auto [w, h] : G[u])
if(!cut[w])
build_centroid_tree(w, u);
}
long long dist(int u, int v)
{
return weight[u] + weight[v] - 2*weight[lca(u, v)];
}
void paint(int v, int u)
{
if(v == -1) return;
ans[v] = min(ans[v], dist(v, u));
paint(CD[v], u);
}
void unpaint(int v, int u)
{
if(v == -1) return;
ans[v] = OO;
unpaint(CD[v], u);
}
long long query(int v, int u, long long d)
{
if(v == -1)
return d;
return query(CD[v], u, min(d, dist(v, u) + ans[v]));
}
void Init(int N, int A[], int B[], int D[]) {
n = N;
for(int i = 0; i < n-1; i++) {
G[ A[i] ].push_back({B[i], D[i]});
G[ B[i] ].push_back({A[i], D[i]});
}
for(int i = 0; i < N; ++i) ans[i] = OO;
build();
build_centroid_tree(0, -1);
}
long long Query(int S, int X[], int T, int Y[]) {
long long rep = OO;
for(int j = 0; j < S; ++j)
paint(X[j], X[j]);
for(int j = 0; j < T; ++j)
rep = min(rep, query(Y[j], Y[j], OO));
for(int j = 0; j < S; ++j)
unpaint(X[j], X[j]);
return rep;
}
// void mount() {
// int A[] = {0, 1, 2, 2, 4, 1};
// int B[] = {1, 2, 3, 4, 5, 6};
// int D[] = {4, 4, 5, 6, 5, 3};
// Init(7, A, B, D);
// }
// int test1() {
// int X[] = {0, 6};
// int Y[] = {3, 4};
// return Query(2, Y, 2, X);
// }
// int test2() {
// int X[] = {0, 1, 3};
// int Y[] = {4, 6};
// return Query(2, Y, 3, X);
// }
// int test3() {
// int X[] = {2};
// int Y[] = {5};
// return Query(1, Y, 1, X);
// }
// int main() {
// mount();
// assert(test1() == 12);
// assert(test2() == 3);
// assert(test3() == 11);
// return 0;
// }
컴파일 시 표준 에러 (stderr) 메시지
factories.cpp: In function 'int find_centroid(int, int, int)':
factories.cpp:74:9: warning: 'next_v' may be used uninitialized in this function [-Wmaybe-uninitialized]
74 | int next_v, cnt = 0;
| ^~~~~~
factories.cpp: In function 'void build_centroid_tree(int, int)':
factories.cpp:74:9: warning: 'next_v' may be used uninitialized in this function [-Wmaybe-uninitialized]
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |