Cod sursa(job #1680587)

Utilizator vnedelcuVictor Andrei Nedelcu vnedelcu Data 8 aprilie 2016 21:33:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <stdio.h>

const int mmax=2000001;
const int nmax= 100001;

int str[18][nmax];

struct edge
{
    int nod,next;
};

edge buff[nmax];
int head[nmax];
int lvl[nmax];
int viz[nmax];

void push(int n1, int n2, int pos)
{
    buff[pos].nod=n2;
    buff[pos].next=head[n1];
    head[n1]=pos;
}

int lca(int n1, int n2)
{
    int i;

    if (lvl[n1] < lvl [n2])
    {
        int aux=n1;
        n1=n2;
        n2=aux;
    }

    int log1,log2;

    for (log1 = 0; (1<<log1) < lvl[n1]; log1++);
    for (log2 = 0; (1<<log2) < lvl[n2]; log2++);

    for (i=log1; i>=0 ; i--)
        if (lvl[n1] - (1<<i) >= lvl[n2])
            n1=str[i][n1];

    if (n1 == n2)
        return n1;

    for (i=log2; i>=0; i--)
        if (str[i][n1] && str[i][n1] != str[i][n2])
        {
            n2=str[i][n2];
            n1=str[i][n1];
        }

    return str[0][n1];
}

void dfs(int nod, int lev)
{
    int i=head[nod];
    lvl[nod]=lev;
    viz[nod]=true;
    while (i)
    {
        if (!viz[buff[i].nod])
            dfs(buff[i].nod,lev+1);
        i=buff[i].next;
    }
}

int main()
{
    FILE *f,*fout;
    int n,m,i,j,u,v;

    f=fopen("lca.in","r");
    fscanf(f,"%d%d",&n,&m);
    fout=fopen("lca.out","w");

    for (i=2; i<=n; i++)
    {
        fscanf(f,"%d",&str[0][i]);
        push(str[0][i],i,i-1);
    }

    for (j=1; (1<<j) <= n; j++)
        for (i=1; i<=n; i++)
            str[j][i]=str[j-1][str[j-1][i]];

    dfs(1,1);

    for (i=1; i<=m; i++)
    {
        fscanf(f,"%d%d",&u,&v);
        fprintf(fout,"%d\n",lca(u,v));
    }

    fclose(f);
    fclose(fout);
}