1 条题解

  • 1
    @ 2022-6-18 8:30:31

    预处理出disidis_i表示点ii到根11的距离,答案是disx+disy2dislca(x,y)dis_x+dis_y-2dis_{lca(x,y)}

    非常容易证明

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    int n, k, b[1000005], x, y, z, tot, h[500005], len[500005], fa[500005][33], dep[500005], lg[500005],
        f[1000005], ans;
    struct node {
        int to, next, w;
    } a[1000005];
    void dfs(long long x, long long fn, long long l) {
        fa[x][0] = fn;
        dep[x] = dep[fn] + 1;
        len[x] = l;
        for (int i = 1; i <= 31; i++) {
            fa[x][i] = fa[fa[x][i - 1]][i - 1];
        }
        for (int i = h[x]; i; i = a[i].next) {
            if (a[i].to != fn) {
                dfs(a[i].to, x, l + a[i].w);
            }
        }
    }
    int lca(int x, int y) {
        if (dep[x] < dep[y]) {
            swap(x, y);
        }
        while (dep[x] > dep[y]) {
            x = fa[x][lg[dep[x] - dep[y]] - 1];
        }
        if (x == y) {
            return x;
        }
        for (int k = lg[dep[x]] - 1; k >= 0; k--) {
            if (fa[x][k] != fa[y][k]) {
                x = fa[x][k], y = fa[y][k];
            }
        }
        return fa[x][0];
    }
    void add(int x, int y, int z) {
        ++tot;
        a[tot].to = y;
        a[tot].next = h[x];
        a[tot].w = z;
        h[x] = tot;
    }
    void answer(int x, int fn) {
        for (int i = h[x]; i; i = a[i].next) {
            if (a[i].to != fn) {
                answer(a[i].to, x);
                f[x] += f[a[i].to];
            }
        }
        ans = max(ans, f[x]);
    }
    int main() {
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
        }
        for (int i = 1; i <= n - 1; i++) {
            cin >> x >> y >> z;
            add(x, y, z);
            add(y, x, z);
        }
        dfs(1, 0, 0);
        cin >> k;
        for (int i = 1; i <= k; i++) {
            cin >> x >> y;
            int t = lca(x, y);
            cout << len[x] + len[y] - 2 * len[t] << endl;
        }
    }
    
    • 1

    信息

    ID
    7
    时间
    1000ms
    内存
    256MiB
    难度
    9
    标签
    递交数
    7
    已通过
    5
    上传者