其他分享
首页 > 其他分享> > HZNU-ACM寒假集训Day9小结

HZNU-ACM寒假集训Day9小结

作者:互联网

LCA

   Luogu P3379 https://www.luogu.com.cn/problem/P3379

   

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
const double PI = acos(-1.0);
typedef long long ll;
using namespace std;

struct Edge {
    int t, next;
}e[500010<<1];  //开两倍
int head[500010], tot;

void add_edge(int x, int y) {
    e[++tot].t = y;
    e[tot].next = head[x];
    head[x] = tot;
}

int depth[500010], fa[500001][22], lg[500001];

void dfs(int now, int fath) {         //now表示当前节点,fath表示其父亲节点
    fa[now][0] = fath;
    depth[now] = depth[fath] + 1;
    for (int i = 1; i <= lg[depth[now]]; i++) {
        fa[now][i] = fa[fa[now][i - 1]][i - 1];   //算法核心
    }
    for (int i = head[now]; i; i = e[i].next) {
        if (e[i].t != fath) dfs(e[i].t, now);
    }
}

int LCA(int x, int y) {
    if (depth[x] < depth[y]) swap(x, y);
    while (depth[x] > depth[y])
        x = fa[x][lg[depth[x] - depth[y]] - 1];    //先跳到同一层
    if (x == y) return x;                          //如果x==y那LCA一定就是x
    for (int k = lg[depth[x]] - 1; k >= 0; k--) {  //不断向上跳
        if (fa[x][k] != fa[y][k]) {                //因为要跳到LCA的下一层所以他们肯定不相等,不相等就跳过去
            x = fa[x][k]; 
            y = fa[y][k];
        }
    }
    return fa[x][0];
}

int main() {
    int n, m, s;
    scanf("%d%d%d", &n, &m, &s);
    for (int i = 1; i <= n - 1; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        add_edge(x, y);
        add_edge(y, x);
    }
    for (int i = 1; i <= n; i++) {         //预先算出log2(i)+1的值,用的时候可以直接调用
        lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
    }
    dfs(s, 0);
    for (int i = 1; i <= m; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        printf("%d\n", LCA(x, y));
    }
    return 0;
}

 

标签:Day9,int,HZNU,d%,ACM,fa,depth,LCA,include
来源: https://www.cnblogs.com/hznumqf/p/12267910.html