Cod sursa(job #2005558)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 27 iulie 2017 14:27:48
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <cstdio>

using namespace std;

FILE *in,*out;

const int nmax = 100007;

int n,m;

int t[nmax],dest[nmax],last[nmax],next[nmax],cont;

void add(int a,int b)
{
    cont ++;
    dest[cont] = b;
    next[cont] = last[a];
    last[a] = cont;

}

int h[nmax], str[nmax][17];

void dfs(int nod,int tat)
{
    for(int p = last[nod]; p; p = next[p])
    {
        if(p != tat)
        {
            h[dest[p]] = h[nod] + 1;
            dfs(dest[p],nod);
        }
    }
}

void precal()
{

    for(int i = 1; i <= n; i ++)
        str[i][0] = t[i];
    for(int j = 1; j <= 16; j ++)
    {
        for(int i = 1; i <= n; i ++)
            str[i][j] = str[str[i][j-1]][j-1];
    }
}

int ask(int a,int b)
{
    if(h[a] > h[b])
    {
        int aux = a;
        a = b;
        b = aux;
    }///b mai jos
    for(int p = 16;p >= 0;p --)
    {
        if(h[str[b][p]] >= h[a])
        {
            b = str[b][p];
        }
    }///a si b sunt la acelasi nivel
    for(int p = 16;p >= 0;p --)
    {
        if(str[a][p] != str[b][p])
        {
            a = str[a][p];
            b = str[b][p];
        }
    }
    if(a == b)
        return a;
    return t[a];
}

int main()
{
    FILE *in = fopen("lca.in","r");
    FILE *out = fopen("lca.out","w");
    fscanf(in,"%d %d",&n,&m);
    for(int i = 2; i <= n; i ++)
    {
        fscanf(in,"%d",&t[i]);
        add(t[i],i);
    }
    h[1] = 1;
    dfs(1,-1);
    precal();
    for(int i = 1;i <= m;i ++)
    {
        int a,b;
        fscanf(in,"%d %d",&a,&b);
        fprintf(out,"%d\n",ask(a,b));
    }
    return 0;
}