首页 > 其他分享 >最近公共祖先(LCA)

最近公共祖先(LCA)

时间:2022-08-16 13:33:15浏览次数:46  
标签:祖先 LCA back dfs int init 公共 -- 500005

#include <bits/stdc++.h>

using namespace std;

int n, m, s;

struct D {
    int d;
    int f[22];
} a[500005];

vector<int> e[500005];

void dfs (int x) {
    a[x].d = a[a[x].f[0]].d + 1;
    for (int i = 0; i < e[x].size(); i++) {
        if (e[x][i] != a[x].f[0]) {
            a[e[x][i]].f[0] = x;
            dfs(e[x][i]);
        }
    }
}

void init () {
    for (int i = 1; i <= 20; i++) {
        for (int j = 1; j <= n; j++) {
            if (a[j].d >= (1 << i)) {
                a[j].f[i] = a[a[j].f[i - 1]].f[i - 1];
            }
        }
    }
}

int lca (int x, int y) {
    if (a[x].d > a[y].d) {
        swap(x, y);
    }
    for (int i = 20; i >= 0; i--) {
        if ((a[y].d - a[x].d) >= (1 << i)) {
            y = a[y].f[i];
        }
    }
    if (x == y) {
        return x;
    }
    for (int i = 20; i >= 0; i--) {
        if (a[x].f[i] != a[y].f[i]) {
            x = a[x].f[i], y = a[y].f[i];
        }
    }
    return a[x].f[0];
}

int main () {
    cin >> n >> m >> s;
    for (int i = 1; i <= n - 1; i++) {
        int x, y;
        cin >> x >> y;
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(s);
    init();
    while (--m) {
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}

标签:祖先,LCA,back,dfs,int,init,公共,--,500005
From: https://www.cnblogs.com/hzt0/p/LeastCommonAncestors.html

相关文章

  • LCA学习笔记
    简介LCA(LowestCommonAncestor)中文名是最近公共祖先。两个节点的最近公共祖先,就是这两个点的公共祖先里面,离根最远的那个。LCA问题的求解有多种方法,如:倍增、Tarjan、树......
  • 最长公共子序列
    前缀型动态规划deflongest_common_seq(s1,s2):ifnots1ornots2:returnm,n=len(s1),len(s2)#dp[i][j]=max(dp[i-1][j],dp[i][j-1......
  • (未完)【算法学习笔记】04 最近公共祖先LCA
    【算法学习笔记】04最近公共祖先LCA原理顾名思义,就是求两点的最近公共祖先(自己也是自己的祖先)。也就是两点在走到根节点的路径上最先遇到的共同的点。向上标记法比较......
  • LCA 相关 && 树链剖分
    LCA基本定义:最近公共祖先简称LCA(LowestCommonAncestor)。两个结点的最近公共祖先,就是这两个点的公共祖先里面,离根最远的那个。简单来讲,就是两个点到根的路径上,深度最深......
  • 9.最长公共子序列问题(动态规划)
    题目描述:给定两个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。输入格式:输入数据有多组,每组有两行,每行为一个长度不超过500的字符串(输入全是大......