이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#pragma GCC optimize("O2")
#include<bits/stdc++.h>
#define ll long long
#define bit(mask, i) ((mask >> i) & 1)
using namespace std;
const ll INF = 1e18;
const int MOD = 1e9 + 7;
const int maxN = 1e5 + 5;
short LOG[maxN << 1];
struct RMQ {
vector<vector<pair<int, int>>> rmq;
RMQ() {};
void build(const vector<pair<int, int>>& V) {
int n = V.size();
for (int i = 2; i <= n; ++i) LOG[i] = LOG[i >> 1] + 1;
rmq.assign(25, V);
int dep = 18;
for (int i = 0; i < dep - 1; ++i)
for (int j = 0; j < n; ++j) {
rmq[i + 1][j] = min(rmq[i][j], rmq[i][min(n - 1, j + (1 << i))]);
}
}
pair<int, int> query(int a, int b) {
if (b <= a) return make_pair(INF, INF);
int dep = LOG[b - a];
return min(rmq[dep][a], rmq[dep][b - (1 << dep)]);
}
};
int n, m, q, H;
vector<pair<int, int>> adj[maxN];
int C[maxN];
bitset<maxN> mark;
int cnt[maxN];
int depth[maxN], in[maxN], out[maxN];
int timer = 0;
ll res[maxN];
ll D[maxN];
ll dist[maxN];
struct LCA {
RMQ rmq;
vector<pair<int, int>> linear;
LCA() {};
LCA(int n) : linear(2 * n) {}
bool in_subtree(int u, int v) {
return in[u] <= in[v] && in[v] <= out[u];
}
void dfs(int u, int dep) {
linear[timer] = {dep, u};
in[u] = timer++;
depth[u] = dep;
cnt[u] = 1;
for (auto [v, w] : adj[u]) {
if (in[v] == -1) {
dist[v] = dist[u] + w;
dfs(v, dep + 1);
cnt[u] += cnt[v];
linear[timer++] = {dep, u};
}
}
out[u] = timer;
}
void build(int root) {
dfs(root, 0);
rmq.build(linear);
}
int query(int a, int b) {
a = in[a], b = in[b];
return rmq.query(min(a, b), max(a, b) + 1).second;
}
ll get_dist(int a, int b) {
return dist[a] + dist[b] - 2ll * dist[query(a, b)];
}
};
LCA lca;
vector<int> sources;
void dfs(int u, int par, int ex) {
if (mark[u]) sources.emplace_back(u);
D[u] = INF;
for (auto [v, w] : adj[u]) {
if (v == par || v == ex) continue;
dfs(v, u, ex);
}
}
void bfs(int exclude) {
queue<int> q;
for (int u : sources) {
D[u] = 0;
q.push(u);
}
sources.clear();
while (!q.empty()) {
int u = q.front(); q.pop();
for (auto [v, w] : adj[u]) {
if (v == exclude) continue;
if (D[v] > D[u] + w) {
D[v] = D[u] + w;
q.push(v);
}
}
}
}
namespace IO {
const int BUFSIZE = 1<<14;
char buf[BUFSIZE + 1], *inp = buf;
bool reacheof;
char get_char() {
if (!*inp && !reacheof) {
memset(buf, 0, sizeof buf);
int tmp = fread(buf, 1, BUFSIZE, stdin);
if (tmp != BUFSIZE) reacheof = true;
inp = buf;
}
return *inp++;
}
template<typename T>
T get() {
int neg = 0;
T res = 0;
char c = get_char();
while (!(c >= '0' && c <= '9') && c != '-' && c != '+') c = get_char();
if (c == '+') { neg = 0; }
else if (c == '-') { neg = 1; }
else res = c - '0';
c = get_char();
while (c >= '0' && c <= '9') {
res = res * 10 + (c - '0');
c = get_char();
}
return neg ? -res : res;
}
};
int read() {
return IO::get<int>();
}
void write(ll xo) {
if (xo > 9)
write(xo / 10);
putchar(xo % 10 + '0');
}
signed main() {
#define TASK "VALLET"
if (fopen(TASK ".inp", "r")) {
freopen(TASK ".inp", "r", stdin);
freopen(TASK ".out", "w", stdout);
}
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
n = read();
m = read();
q = read();
H = read();
--H;
vector<tuple<int, int, int>> edges;
for (int i = 1; i < n; ++i) {
int u, v, w;
u = read();
v = read();
w = read();
--u;
--v;
edges.emplace_back(u, v, w);
adj[u].emplace_back(v, w);
adj[v].emplace_back(u, w);
}
for (int i = 1; i <= m; ++i) {
C[i] = read();
--C[i];
mark[C[i]] = true;
}
for (int i = 0; i < n; ++i) {
in[i] = out[i] = -1;
}
lca = LCA(n);
lca.build(H);
int idx = 0;
vector<tuple<int, int, int>> heavy;
int BLOCKS = sqrt(n);
while (q--) {
int I, R;
I = read();
R = read();
--I;
--R;
auto [u, v, w] = edges[I];
if (depth[u] < depth[v]) swap(u, v);
if (lca.in_subtree(u, R)) {
if (cnt[u] <= BLOCKS) {
dfs(u, -1, v);
bfs(v);
res[++idx] = D[R];
} else {
heavy.emplace_back(u, R, ++idx);
}
} else res[++idx] = -1;
}
for (auto [u, R, pos] : heavy) {
res[pos] = INF;
for (int i = 1; i <= m; ++i) {
if (lca.in_subtree(u, C[i])) {
res[pos] = min(res[pos], lca.get_dist(R, C[i]));
}
}
}
for (int i = 1; i <= idx; ++i) {
if (res[i] == -1) {
putchar('e'); putchar('s'); putchar('c'); putchar('a'); putchar('p'); putchar('e'); putchar('d'); putchar('\n');
}
else if (res[i] == INF) {
putchar('o');
putchar('o');
putchar('\n');
}
else {
write(res[i]);
putchar('\n');
}
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
valley.cpp: In member function 'void LCA::dfs(int, int)':
valley.cpp:66:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
66 | for (auto [v, w] : adj[u]) {
| ^
valley.cpp: In function 'void dfs(int, int, int)':
valley.cpp:100:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
100 | for (auto [v, w] : adj[u]) {
| ^
valley.cpp: In function 'void bfs(int)':
valley.cpp:115:15: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
115 | for (auto [v, w] : adj[u]) {
| ^
valley.cpp: In function 'int main()':
valley.cpp:211:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
211 | auto [u, v, w] = edges[I];
| ^
valley.cpp:223:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
223 | for (auto [u, R, pos] : heavy) {
| ^
valley.cpp:170:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
170 | freopen(TASK ".inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:171:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
171 | freopen(TASK ".out", "w", stdout);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |