zoukankan      html  css  js  c++  java
  • 模板

    令 $f[i][j]$ 表示 $i$ 的 $2^j$ 辈祖先, $f[i][0]$ 就表示 $i$ 的父节点。

    可以得到状态转移方程 $f[i][j]=f[f[i][j-1]][j-1]$ 。当没有 $2^j$ 辈祖先时 $f[i][j]=0$ 

    一遍 DFS 计算即可

    void dfs(int u, int father) {
        dep[u] = dep[father] + 1;  // dep[x] 表示 x 的深度,在查询时会用到
        for (int i = 0; i <= 19; i++)
            f[u][i + 1] = f[f[u][i]][i];  // 预处理
        for (int i = first[u]; i; i = next[i]) {/ 链式前向星
            int v = go[i];
            if (v == father)
                continue;
            f[v][0] = u;  // f[v][0] 表示 v 的父亲
            dfs(v, u);
        }
    }

    查询

    先往上2进制跳到同深度,再2进制一起往上跳。

    int lca(int x, int y) {
        if (dep[x] < dep[y])
            swap(x, y);  // 步骤 1
        for (int i = 20; i >= 0; i--) {   // 步骤 2
            if (dep[f[x][i]] >= dep[y])
                x = f[x][i];
            if (x == y)
                return x;
        }
        for (int i = 20; i >= 0; i--)  // 步骤 3
            if (f[x][i] != f[y][i]) {
                x = f[x][i];
                y = f[y][i];
            }
        return f[x][0];
    }
  • 相关阅读:
    线段树模板
    树状数组练习
    树状数组模板
    codeforce——思维dp
    fib博弈
    寒假总结
    相邻的数互质
    大数取模运算
    阶乘因式分解(一)
    1和0既非素数也非合数
  • 原文地址:https://www.cnblogs.com/Yinku/p/10472831.html
Copyright © 2011-2022 走看看