某算法的板子练习(二)

题目:P3379

树上LCA,本蒟蒻罕见的一遍A掉的板子

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;

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

int n,m,s;
int cnt;
int head[500005],nxt[1000005],v[1000005];
int dep[500005],f[500005][21];

void add(int a,int b)
{
    v[++cnt]=b;
    nxt[cnt]=head[a];
    head[a]=cnt;
}

void dfs(int x,int fa)
{
    dep[x]=dep[fa]+1;
    for(int i=0;i<=19;i++)
        f[x][i+1]=f[f[x][i]][i];
    for(int i=head[x];i;i=nxt[i])
    {
        int t=v[i];
        if(t==fa) continue;
        f[t][0]=x;
        dfs(t,x);
    }
}

int LCA(int a,int b)
{
    int i;
    if(dep[a]<dep[b])
    {
        int t=a; a=b; b=t;
    }
    for(i=20;i>=0;i--)
    {
        if(dep[a]-(1<<i)>=dep[b]) a=f[a][i];
        if(a==b) return a;
    }
    for(i=20;i>=0;i--)
    {
        if(f[a][i]!=f[b][i])
            a=f[a][i],b=f[b][i];
    }
    return f[a][0];
}

int main()
{
    int i,a,b;
    n=read(); m=read(); s=read();
    for(i=1;i<=n-1;i++)
    {
        a=read();
        b=read();
        add(a,b);
        add(b,a);
    }
    dfs(s,0);
    for(i=1;i<=m;i++)
    {
        a=read(); b=read();
        printf("%d\n",LCA(a,b));
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/llllllpppppp/p/9932506.html