Cod sursa(job #1985313)

Utilizator demetriad-dagpagDavid Demetriad demetriad-dagpag Data 27 mai 2017 14:06:59
Problema Lowest Common Ancestor Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 1.51 kb
#include <stdio.h>
#include <stdlib.h>
int next[200001],nod[200001],lista[100001],ti[100001],to[100001],nr,timp;
int s[100001][18];
void add(int x,int y)
{
    nr++;
    next[nr]=lista[x];
    lista[x]=nr;
    nod[nr]=y;
}
void dfs(int x)
{
    int z;
    ti[x]=++timp;
    z=lista[x];
    while(z)
    {
        dfs(nod[z]);
        z=next[z];
    }
    to[x]=++timp;
}
int stramos(int x,int y)
{
    return (ti[x]<=ti[y] && to[y]<=to[x]);
}
int lca(int x,int y)
{
    int pas=17,z;
    if(!stramos(x,y) && !stramos(y,x)){
        while(pas>=0)
        {
            z=s[x][pas];
            if(z && (to[z]<ti[y] || ti[z]>to[y])) x=z;
            pas--;
        }
        return s[x][0];
    }
    if(stramos(x,y)) return x;
    return y;
}
int main()
{
    int n,m,i,x,j,z,y;
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(i=2; i<=n; i++)
    {
        scanf("%d",&x);
        add(x,i);
    }
    dfs(1);
    for(i=1; i<=n; i++){
        z=lista[i];
        while(z)
        {
            y=nod[z];
            s[y][0]=i;
            z=next[z];
        }
    }
    for(j=1; j<=17; j++)
        for(i=1; i<=n; i++)
        {
            z=lista[i];
            while(z)
            {
                y=nod[z];
                s[y][j]=s[i][j-1];
                z=next[z];
            }
        }
    for(i=1; i<=m; i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",lca(x,y));
    }

    return 0;
}