题解 P3379 【【模板】最近公共祖先(LCA)】

· · 题解

这是一个找不同游戏

#include<bits/stdc++.h>
using namespace std;
int depth[500001],fa[500001][22],lg[500001],head[500001];
int cnt;
struct rec
{
    int to;
    int nxt;
}e[1000001];
void add(int x,int y)
{
    e[++cnt].to=y; 
    e[cnt].nxt=head[x];
    head[x]=cnt;
}
void dfs(int f,int fath)
{
    depth[f]=depth[fath]+1;
    fa[f][0]=fath;
    for(int i=1;(1<<i)<=depth[f];i++)
        fa[f][i]=fa[fa[f][i-1]][i-1];
    for(int i=head[f];i;i=e[i].nxt)
        if(e[i].to!=fath)
            dfs(e[i].to,f);
}
int main()
{
    int n,m,s;
    int x,y;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs(s,0);
    for(int i=1;i<=n;i++)
        lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    while(m--)
    {
        scanf("%d%d",&x,&y);
        if(depth[x]<depth[y])
            swap(x,y);
        while(depth[x]>depth[y])
            x=fa[x][lg[depth[x]-depth[y]]-1];
        if(x==y)
        {
            cout<<x<<endl;
            continue;
        }
        for(int k=lg[depth[x]]-1;k>=0;k--)
            if(fa[x][k]!=fa[y][k])
            {
                x=fa[x][k];
                y=fa[y][k];
            }
        cout<<fa[x][0]<<endl;
    }
    return 0;
}

70分

#include<bits/stdc++.h>
using namespace std;
int depth[500001],fa[500001][22],lg[500001],head[500001];
int cnt;
struct rec
{
    int to;
    int nxt;
}e[1000001];
void add(int x,int y)
{
    e[++cnt].to=y; 
    e[cnt].nxt=head[x];
    head[x]=cnt;
}
void dfs(int f,int fath)
{
    depth[f]=depth[fath]+1;
    fa[f][0]=fath;
    for(int i=1;(1<<i)<=depth[f];i++)
        fa[f][i]=fa[fa[f][i-1]][i-1];
    for(int i=head[f];i;i=e[i].nxt)
        if(e[i].to!=fath)
            dfs(e[i].to,f);
}
int main()
{
    int n,m,s;
    int x,y;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1;i<=n-1;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,y);
        add(y,x);
    }
    dfs(s,0);
    for(int i=1;i<=n;i++)
        lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    while(m--)
    {
        scanf("%d%d",&x,&y);
        if(depth[x]<depth[y])
            swap(x,y);
        while(depth[x]>depth[y])
            x=fa[x][lg[depth[x]-depth[y]]-1];
        if(x==y)
        {
            printf("%d\n",x);
            continue;
        }
        for(int k=lg[depth[x]]-1;k>=0;k--)
            if(fa[x][k]!=fa[y][k])
            {
                x=fa[x][k];
                y=fa[y][k];
            }
        printf("%d\n",fa[x][0]);
    }
    return 0;
}

满分

谨以此篇题解表达,此题卡printf!!!