結果

問題 No.1094 木登り / Climbing tree
ユーザー granddaifukugranddaifuku
提出日時 2020-06-25 20:49:46
言語 C++14
(gcc 12.3.0 + boost 1.83.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
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 767 ms
41,028 KB
testcase_02 AC 129 ms
50,372 KB
testcase_03 AC 172 ms
5,248 KB
testcase_04 AC 167 ms
19,348 KB
testcase_05 AC 288 ms
36,040 KB
testcase_06 AC 366 ms
14,668 KB
testcase_07 AC 792 ms
41,028 KB
testcase_08 AC 793 ms
41,032 KB
testcase_09 AC 772 ms
40,900 KB
testcase_10 AC 792 ms
41,032 KB
testcase_11 AC 800 ms
41,028 KB
testcase_12 AC 788 ms
41,028 KB
testcase_13 AC 809 ms
41,032 KB
testcase_14 AC 772 ms
41,032 KB
testcase_15 AC 390 ms
13,312 KB
testcase_16 AC 593 ms
39,112 KB
testcase_17 AC 497 ms
24,280 KB
testcase_18 AC 475 ms
18,896 KB
testcase_19 AC 565 ms
32,840 KB
testcase_20 AC 774 ms
40,896 KB
testcase_21 AC 515 ms
25,816 KB
testcase_22 AC 795 ms
40,864 KB
testcase_23 AC 776 ms
41,044 KB
testcase_24 AC 778 ms
40,900 KB
testcase_25 AC 768 ms
40,900 KB
testcase_26 AC 784 ms
41,156 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

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

0