码迷,mamicode.com
首页 > 其他好文 > 详细

Nearest Common Ancestor

时间:2019-03-22 19:06:28      阅读:119      评论:0      收藏:0      [点我收藏+]

标签:head   bsp   倍增   color   lca   namespace   pre   algo   algorithm   

POJ上的题,其实就是LCA板子。先预处理每个点倍增祖先,然后每组询问先使x和y达到同一深度,然后一起往上跳到公共祖先的+1深度的点。

die码:

#include<cstdio>
#include<algorithm>
#define maxn 500010
using namespace std;
int head[maxn],nxt[maxn<<1],to[maxn<<1],cnt;
int deep[maxn],f[maxn][21];
inline void add(int x,int y)
{
    nxt[++cnt]=head[x];
    head[x]=cnt;
    to[cnt]=y;
}
inline void dfs(int id,int fa)
{
    deep[id]=deep[fa]+1;
    f[id][0]=fa;
    for(int i=1;i<=20;i++)
        f[id][i]=f[f[id][i-1]][i-1];
    for(int i=head[id];i;i=nxt[i])
    {
        if(to[i]==fa)
            continue;
        dfs(to[i],id);
    }
}
inline int lca(int x,int y)
{
    if(deep[x]<deep[y])
        swap(x,y);
    for(int i=20;i>=0;i--)
        if(deep[f[x][i]]>=deep[y])
            x=f[x][i];
    if(x==y)
        return y;
    for(int i=20;i>=0;i--)
    {
        if(f[x][i]==f[y][i])
            continue;
        x=f[x][i],y=f[y][i];
    }
    return f[x][0];
}
int main()
{
    int n,m,s;
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1,a,b;i<n;i++)
    {
        scanf("%d%d",&a,&b);
        add(a,b),add(b,a);
    }
    dfs(s,0);
    for(int i=1,x,y;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }
    return 0;
}

 

Nearest Common Ancestor

标签:head   bsp   倍增   color   lca   namespace   pre   algo   algorithm   

原文地址:https://www.cnblogs.com/charlesss/p/10579850.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!