結果

問題 No.1094 木登り / Climbing tree
ユーザー MayimgMayimg
提出日時 2020-07-03 14:22:33
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 673 ms / 2,000 ms
コード長 4,722 bytes
コンパイル時間 3,139 ms
コンパイル使用メモリ 213,372 KB
実行使用メモリ 70,364 KB
最終ジャッジ日時 2024-04-25 18:46:05
合計ジャッジ時間 19,595 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
6,816 KB
testcase_01 AC 637 ms
59,056 KB
testcase_02 AC 186 ms
70,364 KB
testcase_03 AC 53 ms
6,940 KB
testcase_04 AC 170 ms
27,520 KB
testcase_05 AC 361 ms
51,792 KB
testcase_06 AC 204 ms
20,736 KB
testcase_07 AC 626 ms
59,124 KB
testcase_08 AC 646 ms
59,200 KB
testcase_09 AC 625 ms
59,056 KB
testcase_10 AC 643 ms
59,060 KB
testcase_11 AC 630 ms
59,028 KB
testcase_12 AC 632 ms
59,044 KB
testcase_13 AC 621 ms
59,156 KB
testcase_14 AC 649 ms
59,004 KB
testcase_15 AC 188 ms
18,176 KB
testcase_16 AC 468 ms
54,328 KB
testcase_17 AC 311 ms
33,536 KB
testcase_18 AC 259 ms
25,728 KB
testcase_19 AC 442 ms
45,952 KB
testcase_20 AC 673 ms
59,064 KB
testcase_21 AC 356 ms
35,840 KB
testcase_22 AC 637 ms
59,032 KB
testcase_23 AC 622 ms
58,964 KB
testcase_24 AC 632 ms
59,084 KB
testcase_25 AC 624 ms
59,172 KB
testcase_26 AC 649 ms
59,180 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#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;
}
0