20分求助
查看原帖
20分求助
516836
Carey_chen楼主2023/3/9 22:00

代码:

#include <bits/stdc++.h>

using namespace std;

vector <int> G[500010];
int fa[500010], dep[500010];
int dp[500010][32];

void Build(int u = 1)
{

    for(auto v : G[u])
    {
        if(v != fa[u])
        {
            fa[v] = u;
            dep[v] = dep[u] + 1;

            Build(v);
        }
    }
}

int n, m, s;

void Pre()
{
    for(int i = 1; i <= n; i++)
    {
        dp[i][0] = fa[i];
    }

    for(int i = 1; i <= 20; i++)
    {
        for(int j = 1; j <= n; j++)
        {
            dp[i][j] = dp[dp[i][j-1]][j-1];
        }
    }
}

int jump(int u, int k)
{
    for(int i = 0; i <= 20; i++)
    {
        if((k >> i & 1) == 1)
        {
            u = dp[u][i];
        }
    }

    return u;
}

int LCA(int u, int v)
{
    if(dep[u] < dep[v])
    {
        swap(u, v);
    }

    u = jump(u, dep[u] - dep[v]);

    for(int i = log2(dep[u]) - 1; i >= 0; i--)
    {
        if(dp[u][i] != dp[v][i] && (dp[v][i] != 0 && dp[u][i] != 0))
        {
            u = dp[u][i];
            v = dp[v][i];
        }
    }

    if(u == v)
    {
        return u;
    }
    else
    {
        return fa[u];
    }
}

int main()
{
    #ifdef Carey
        freopen("P3379_1.in", "r", stdin);
        freopen("P3379_1.out", "w", stdout);
    #endif

    scanf("%d %d %d", &n, &m, &s);

    printf("1");
    for(int i = 1; i <= (n-1); i++)
    {
        int u, v;

        scanf("%d %d", &u, &v);

        G[u].push_back(v);
        G[v].push_back(u);
    }

    Build(s);
    Pre();

    while(m--)
    {
        int u, v;

        scanf("%d %d", &u, &v);
        printf("%d\n", LCA(u, v));
    }

    return 0;
}
2023/3/9 22:00
加载中...