結果
| 問題 |
No.1094 木登り / Climbing tree
|
| ユーザー |
|
| 提出日時 | 2020-06-25 20:49:46 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 809 ms / 2,000 ms |
| コード長 | 2,871 bytes |
| コンパイル時間 | 2,176 ms |
| コンパイル使用メモリ | 176,404 KB |
| 実行使用メモリ | 50,372 KB |
| 最終ジャッジ日時 | 2024-11-08 06:00:24 |
| 合計ジャッジ時間 | 21,802 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 26 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)n; ++i)
#define FOR(i, a, b) for(int i = a; i < (int)b; ++i)
#define rrep(i, n) for(int i = ((int)n - 1); i >= 0; --i)
using ll = long long;
using ld = long double;
const ll INF = 1e18;
const int Inf = 1e9;
const double EPS = 1e-9;
const int MOD = 1e9 + 7;
template <typename T>
class LCA {
public:
int n, log_v = 0;
vector<int> depth;
vector<T> costs;
vector<vector<int> > to;
vector<vector<T> > cost;
vector<vector<int> > parent;
LCA() {}
LCA(int n_): n(n_) {
while ((1 << log_v) < n) ++log_v;
depth.assign(n, 0);
costs.assign(n, 0);
to = vector<vector<int> >(n);
cost = vector<vector<T> >(n);
parent = vector<vector<int> >(log_v, vector<int>(n, 0));
}
void init(int root = 0) {
dfs(root);
rep (i, log_v - 1) {
rep (j, n) parent[i + 1][j] = parent[i][parent[i][j]];
}
}
void addEdge(int u, int v, T c = 0) {
to[u].push_back(v);
to[v].push_back(u);
cost[u].push_back(c);
cost[v].push_back(c);
}
void dfs(int v, int p = -1, int d = 0, T c = 0) {
if (p != -1) parent[0][v] = p;
depth[v] = d;
costs[v] = c;
rep (i, to[v].size()) {
int e = to[v][i];
if (e == p) continue;
dfs(e, v, d + 1, c + cost[v][i]);
}
}
int query(int u, int v) {
if (depth[u] > depth[v]) swap(u, v);
rep (i, log_v) {
if ((depth[v] - depth[u]) >> i & 1) v = parent[i][v];
}
if (u == v) return u;
for (int i = log_v - 1; i >= 0; --i) {
if (parent[i][u] != parent[i][v]) {
u = parent[i][u];
v = parent[i][v];
}
}
return parent[0][u];
}
int length(int u, int v) {
return depth[u] + depth[v] - 2 * depth[query(u, v)];
}
T dist(int u, int v) {
return costs[u] + costs[v] - 2 * costs[query(u, v)];
}
// is x on the path u - v
bool isOnPath(int u, int v, int x) {
return length(u, x) + length(v, x) == length(u, v);
}
};
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(0);
int n, q;
cin >> n;
LCA<int> lca = LCA<int>(n);
rep (i, n - 1) {
int a, b, c;
cin >> a >> b >> c;
lca.addEdge(a - 1, b - 1, c);
}
lca.init();
cin >> q;
rep (i, q) {
int s, t;
cin >> s >> t;
cout << lca.dist(s - 1, t - 1) << endl;
}
return 0;
}