模板 - 图论 - 树 - 最近公共祖先

Posted yinku

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 - 图论 - 树 - 最近公共祖先相关的知识,希望对你有一定的参考价值。

令 $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];
}

 

以上是关于模板 - 图论 - 树 - 最近公共祖先的主要内容,如果未能解决你的问题,请参考以下文章

在线查询树上最近公共祖先模板

洛谷P3379 模板最近公共祖先(LCA)

图论-最近公共祖先-在线树上倍增

模板题大全(更新中)

洛谷 P3379 模板最近公共祖先(LCA)

『图论』LCA 最近公共祖先