이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
#define ll long long
#define bit(mask, i) ((mask >> i) & 1)
using namespace std;
void __print(short x) {cerr << x;}
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}
template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ", "; __print(x.second); cerr << '}';}
template <typename... A>
void __print(const tuple<A...> &t) { bool first = true; cerr << '{'; apply([&first](const auto &...args) { ((cerr << (first ? "" : ","), __print(args), first = false), ...); }, t); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; for (auto &i: x) cerr << (f++ ? ", " : ""), __print(i);}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#define deb(x...) cerr << "\e[91m" << "[In "<<__func__<<"() : line " <<__LINE__<<" ] : [" << #x << "] = ["; _print(x); cerr << "\n\e[39m";
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 = 20;
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];
bool mark[maxN];
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);
}
}
}
}
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);
cin >> n >> m >> q >> H;
--H;
vector<tuple<int, int, int>> edges;
for (int i = 1; i < n; ++i) {
int u, v, w;
cin >> u >> v >> w;
--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) {
cin >> C[i];
--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;
cin >> I >> R;
--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) cout << "escaped\n";
else if (res[i] == INF) cout << "oo\n";
else cout << res[i] << '\n';
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
valley.cpp: In function 'int main()':
valley.cpp:154:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
154 | freopen(TASK ".inp", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
valley.cpp:155:14: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
155 | 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... |