社区讨论

3个点蜜汁RE,求助大佬!

P3379【模板】最近公共祖先(LCA)参与者 2已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@mi6xzy1a
此快照首次捕获于
2025/11/20 12:39
4 个月前
此快照最后确认于
2025/11/20 12:39
4 个月前
查看原帖
CPP
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int N = 5e5 + 5;

int n, m, s;
int u, v;
int x, y;
int head[N];  //每个点连出去的第一条边的编号
int cnt = 0;  //边的数量
int depth[N]; //每个边的深度
int vis[N];   //判断每个点是否走过
int f[N][30];

struct EDGE {
    int s; //这个边的起点
    int e; //这个边的终点
    int w; //这个边的权值
    int nxt; //这个边的下一条边的指针
} Edge[N];

void add(int u, int v, int w) {
    ++cnt;
    Edge[cnt].s = u;
    Edge[cnt].e = v;
    Edge[cnt].w = w;
    Edge[cnt].nxt = head[u];
    head[u] = cnt;
}

void dfs(int x, int dep) {
    for (register int i = 1; i < 25; ++i) 
        f[x][i] = f[f[x][i - 1]][i - 1];
    for (register int i = head[x]; i != 0 && Edge[i].s == x; i = Edge[i].nxt) {
        if (vis[Edge[i].e]) continue;
        vis[Edge[i].e] = true;
        f[Edge[i].e][0] = x;
        depth[Edge[i].e] = dep + 1;
        dfs(Edge[i].e, dep + 1);
    }
}

int lca(int a, int b) {
    if (depth[a] < depth[b]) swap(a, b);
    int dis = depth[a] - depth[b];
    for (register int i = 0; (1 << i) <= dis; ++i) 
        if ((1 << i) & dis) a = f[a][i];
    if (a == b) return a;
    for (register int i = 25; i >= 0; --i) {
        if (f[a][i] != f[b][i])
            a = f[a][i], b = f[b][i];
    }
    return f[a][0];
}

int read() {
    int s = 0, w = 1;
    char ch = getchar();
    while (ch <='0' || ch > '9') {
        if (ch == '-') w = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        s = s * 10 + ch - '0';
        ch = getchar();
    }
    return s * w;
}

inline void write(int x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) write(x / 10);
    putchar(x % 10 + '0');
}

int main(int argc, char *argv[]) {
    n = read(), m = read(), s = read();
    for (register int i = 1; i < n; ++i) {
        u = read(), v = read();
        add(u, v, 1);
        add(v, u, 1);
    }
    vis[s] = true;
    dfs(s, 0);
    for (register int i = 1; i <= m; ++i) {
        x = read(), y = read();
        write(lca(x, y)), putchar('\n');
    }
    return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...