結果
| 問題 |
No.1094 木登り / Climbing tree
|
| ユーザー |
|
| 提出日時 | 2020-07-03 14:22:33 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 507 ms / 2,000 ms |
| コード長 | 4,722 bytes |
| コンパイル時間 | 2,259 ms |
| コンパイル使用メモリ | 212,628 KB |
| 最終ジャッジ日時 | 2025-01-11 14:04:20 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 26 |
ソースコード
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
/////////////////////////////////////////////////////////////////////////
// LCA
/////////////////////////////////////////////////////////////////////////
class LowestCommonAncestor {
public:
LowestCommonAncestor();
LowestCommonAncestor(const vector<vector<int>>& g, int r);
LowestCommonAncestor(const vector<int> g[], int r, int siz);
~LowestCommonAncestor();
void build(const vector<vector<int>>& g, int r);
void build(const vector<int> g[], int r, int siz);
inline int get(int u, int v) const;
inline int getParent(int cur, int u) const;
inline int getDepth(int cur) const;
inline void debugTree () const;
private:
void initialize();
void dfs(int cur, int par, int d);
static constexpr int MAX_SIZE = 30;
vector<vector<int>> graph;
vector<vector<int>> parent;
vector<int> depth;
int bit_;
int root;
};
LowestCommonAncestor::LowestCommonAncestor() {};
LowestCommonAncestor::LowestCommonAncestor(const vector<vector<int>>& g, int r = -1)
: graph(g), root(r) {
if (root == -1) root = 0;
initialize();
}
LowestCommonAncestor::LowestCommonAncestor(const vector<int> g[], int r = -1, int siz = -1)
: root(r) {
assert(siz > 0);
if (root == -1) root = 0;
graph.resize(siz);
for (int i = 0; i < siz; i++) for (auto& j : g[i]) graph[i].push_back(j);
initialize();
}
LowestCommonAncestor::~LowestCommonAncestor() {};
void LowestCommonAncestor::build(const vector<vector<int>>& g, int r = -1) {
root = r;
graph = g;
if (root == -1) root = 0;
initialize();
}
void LowestCommonAncestor::build(const vector<int> g[], int r = -1, int siz = -1) {
assert(siz > 0);
root = r;
graph.resize(siz);
for (int i = 0; i < siz; i++) for (auto& j : g[i]) graph[i].push_back(j);
initialize();
}
inline int LowestCommonAncestor::get(int u, int v) const {
assert(u >= 0 && u < (int) graph.size());
assert(v >= 0 && v < (int) graph.size());
if (depth[u] > depth[v]) swap(u, v);
for (int i = 0; i < bit_; ++i) if (((depth[v] - depth[u]) >> i) & 1) v = parent[v][i];
if (u == v) return u;
for (int i = bit_ - 1; i >= 0; --i) if (parent[u][i] != parent[v][i]) u = parent[u][i], v = parent[v][i];
return parent[u][0];
}
inline int LowestCommonAncestor::getParent(int cur, int u = 0) const {
if ((int) parent[cur].size() <= u) return -1;
//assert(cur >= 0 && cur < (int) parent.size());
//assert(u >= 0 && (int) parent[cur].size() > u);
return parent[cur][u];
}
inline int LowestCommonAncestor::getDepth(int cur) const {
assert(cur >= 0 && cur < (int) depth.size());
return depth[cur];
}
void LowestCommonAncestor::initialize() {
bit_ = 1;
while ((1 << bit_) < (int) graph.size()) ++bit_;
parent = vector<vector<int>>((int) graph.size(), vector<int>(bit_));
depth.assign((int) graph.size(), -1);
dfs(root, -1, 0);
for (int i = 0; i < bit_ - 1; ++i) {
for (int v = 0; v < (int) graph.size(); ++v) {
if (depth[v] == -1) continue;
if (parent[v][i] < 0) parent[v][i + 1] = -1;
else parent[v][i + 1] = parent[parent[v][i]][i];
}
}
}
void LowestCommonAncestor::dfs(int cur, int par, int d) {
parent[cur][0] = par;
depth[cur] = d;
for (auto& child : graph[cur]) if (child != par) dfs(child, cur, d + 1);
}
void LowestCommonAncestor::debugTree () const {
cerr << "size " << parent.size() << endl;
for (int i = 0; i < (int) parent.size(); i++) {
cerr << "the parent of " << i << " -> " << parent[i][0] << endl;
}
cerr << endl;
for (int i = 0; i < (int) graph.size(); i++) {
cerr << "the neighbor of " << i << " -> ";
for (const int& j : graph[i]) cerr << j << " ";
cerr << endl;
}
}
using LCA = LowestCommonAncestor;
/////////////////////////////////////////////////////////////////////////
// END LCA
/////////////////////////////////////////////////////////////////////////
vector<int> dist;
vector<vector<pair<int, int>>> g;
vector<vector<int>> gg;
void dfs (int cur, int par) {
for (auto child : g[cur]) if (child.first != par) {
dist[child.first] = dist[cur] + child.second;
dfs(child.first, cur);
}
}
signed main() {
ios::sync_with_stdio(false); cin.tie(0);
int n;
cin >> n;
g = vector<vector<pair<int, int>>>(n);
gg = vector<vector<int>>(n);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
u--;
v--;
int c;
cin >> c;
g[u].emplace_back(v, c);
g[v].emplace_back(u, c);
gg[u].push_back(v);
gg[v].push_back(u);
}
dist = vector<int>(n);
dfs(0, -1);
LCA lca(gg);
int q;
cin >> q;
while (q--) {
int u, v;
cin >> u >> v;
u--;
v--;
cout << dist[u] - dist[lca.get(u, v)] * 2 + dist[v] << '\n';
}
return 0;
}