洛谷 3379_【模板】最近公共祖先(LCA)

来源:互联网 发布:mac pr防抖 编辑:程序博客网 时间:2024/06/05 08:37

题目描述

如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先。


#include <stdio.h>#define maxn 500001struct edge{    int to, next;}e[maxn * 2];int ls[maxn * 2], dep[maxn], f[maxn][21];bool v[maxn];int dfs(int now, int de, int fa){    f[now][0] = fa;    dep[now] = de;    v[now] = 1;    for (int i = ls[now]; i; i = e[i].next)    {        if (v[e[i].to] == 0)            dfs(e[i].to, de + 1, now);    }}int LCA(int l, int r){    if (dep[l] < dep[r])        {l ^= r; r ^= l; l ^= r;}    for (int i = 20; i >= 0; i--)        if (dep[r] <= dep[f[l][i]])            l = f[l][i];    if (l == r) return l;    for (int i = 20; i >= 0; i--)        if (f[l][i] != f[r][i])        {            l = f[l][i];            r = f[r][i];        }    return f[l][0];}int main(){    int n, m, root;    scanf("%d%d%d", &n, &m, &root);    v[root] = 1;    int l = 0;    for (int i = 1; i < n; i++)    {        int x, y;        scanf("%d%d", &x, &y);        e[++l] = (edge) {y, ls[x]};        ls[x] = l;        e[++l] = (edge) {x, ls[y]};        ls[y] = l;    }    dfs(root, 1, 0);    for (int j = 1; j <= 20; j++)        for (int i = 1; i <= n; i++)            f[i][j] = f[f[i][j - 1]][j - 1];    for (int i = 1; i <= m; i++)    {        int l, r;        scanf("%d%d", &l, &r);        printf("%d\n", LCA(l, r));    }}
原创粉丝点击