题目:$\textsf{\textcolor{#FFC116}{P3379 【模板】最近公共祖先(LCA)}}$

提交记录:

错误原因:

  1. 21 行,在 x 的祖先节点的深度等于 y 时也要跳,否则跳不到 y。

    错误示范:

    for (int i = 19; i >= 0; i--)
        if (deep[fa[x][i]] > deep[y])
            x = fa[x][i];
    

    正解:

    for (int i = 19; i >= 0; i--)
        if (deep[fa[x][i]] >= deep[y])
            x = fa[x][i];
    

  2. $\log 5 \times 10^5 \approx 19$,数组要开下标 $0 \sim 19$ 即 $20$。

    错误示范:

    int n, m, s, deep[LEN], fa[LEN][19];
    

    正解:

    int n, m, s, deep[LEN], fa[LEN][20];
    

#include <bits/stdc++.h>
using namespace std;
const int LEN = 5e5 + 5;
vector<int> G[LEN];
int n, m, s, deep[LEN], fa[LEN][20];
void dfs(int x, int father)
{
    deep[x] = deep[father] + 1;
    fa[x][0] = father;
    for (int i = 1; (1 << i) <= deep[x]; i++)
        fa[x][i] = fa[fa[x][i - 1]][i - 1];
    for (int i = 0; i < G[x].size(); i++)
        if (G[x][i] != father)
            dfs(G[x][i], x);
}
int lca(int x, int y)
{
    if (deep[x] < deep[y])
        swap(x, y);
    for (int i = 19; i >= 0; i--)
        if (deep[fa[x][i]] >= deep[y])
            x = fa[x][i];
    if (x == y)
        return x;
    for (int i = 19; i >= 0; i--)
        if (fa[x][i] != fa[y][i])
        {
            x = fa[x][i];
            y = fa[y][i];
        }
    return fa[x][0];
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m >> s;
    for (int i = 1; i <= n - 1; i++)
    {
        int x, y;
        cin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs(s, 0);
    for (int i = 1; i <= m; i++)
    {
        int a, b;
        cin >> a >> b;
        cout << lca(a, b) << "\n";
    }
    return 0;
}