P-3379-LCA(倍增模板)

题目
Reaper
在这里插入图片描述
输入样例#1:
5 5 4
3 1
2 4
5 1
1 4
2 4
3 2
3 5
1 2
4 5

输出样例#1:
4
4
1
4
4

时空限制:1000ms,128M
数据:N<=500000,M<=500000

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define m(a,b) memset(a,b,sizeof a)
#define en '\n'
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f,N=5e5+5,K=19,M=N;
int dep[N],fa[N][K+5];
int head[N],tot;
struct Edge{int to,nex;}edge[M<<1];
void add(int from,int to)
{
    edge[++tot]=(Edge){to,head[from]};head[from]=tot;
    edge[++tot]=(Edge){from,head[to]};head[to]=tot;
}
void dfs(int x)
{
    for(int i=1;(1<<i)<=dep[x];i++)
        fa[x][i]=fa[fa[x][i-1]][i-1];
    for(int i=head[x];i;i=edge[i].nex)
    {
        int y=edge[i].to;
        if(y==fa[x][0])
            continue;
        dep[y]=dep[x]+1;
        fa[y][0]=x;
        dfs(y);
    }
}
int lca(int x,int y)
{
    if(dep[x]<dep[y])
        swap(x,y);
//    int i;
//    for(i=0;(1<<i)<=dep[x];i++);//上限i
//    --i;
    for(int j=K;j>=0;j--)//将x,y提到同一高度.
        if(dep[x]-(1<<j)>=dep[y])
            x=fa[x][j];
    if(x==y)
        return x;
    for(int j=K;j>=0;j--)
        if(fa[x][j]!=fa[y][j]) //假若不找上限i(否则将K在这里替换为i)的话,多组样例应该m(fa,-1);
            x=fa[x][j],y=fa[y][j];
    return fa[x][0];
}
int main()
{

    int n,m,s;
    scanf("%d%d%d",&n,&m,&s);
//    m(head,0),tot=0;
//    m(fa,-1),dep[s]=0;多组样例必须加!!!
    for(int i=1;i<=n-1;i++)
    {
        int a,b;scanf("%d%d",&a,&b);
        add(a,b);
    }
    dfs(s);
    while(m--)
    {
        int a,b;scanf("%d%d",&a,&b);
        printf("%d\n",lca(a,b));
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/90111307
今日推荐