Cod sursa(job #1184903)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 14 mai 2014 15:52:46
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

const int Nmax = 100000 + 2;

vector <int> G[Nmax];
int depth[Nmax];
int tata[Nmax];
int group[Nmax];
int size[Nmax];
int N, M, H, SQRT;

void DFS( int nod, int d, int gr )
{
    depth[nod] = d;
    group[nod] = gr;
    size[nod] = 1;
    int hv = 0;

    if ( d % SQRT == 0 )
    {
        gr = nod;
    }

    for ( auto x: G[nod] )
    {
        if ( tata[x] == 0 )
        {
            tata[x] = nod;
            DFS( x, d + 1, gr );
            size[nod] += size[x];

            if ( size[x] > size[hv] )
            {
                hv = x;
            }
        }
    }

    if ( hv == 0 )
    {
        group[nod] = ++H;
    }
    else
    {
        group[nod] = group[hv];
    }
}

int lca( int x, int y )
{
    while ( group[x] != group[y] )
    {
        if ( depth[x] > depth[y] )
                x = tata[x];
        else
                y = tata[y];
    }

    while ( x != y )
    {
        if ( depth[x] > depth[y] )
                x = tata[x];
        else
                y = tata[y];
    }

    return x;
}

int main()
{
    ifstream f("lca.in");
    ofstream g("lca.out");

    f >> N >> M;

    for ( int i = 2, a; i <= N; ++i )
    {
        f >> a;
        G[a].push_back( i );
    }

    SQRT = 1;

    while ( SQRT * SQRT < N ) SQRT++;

    DFS( 1, 0, 1 );

    for ( int i = 1, a, b; i <= M; ++i )
    {
        f >> a >> b;
        g << lca( a, b ) << "\n";
    }

    return 0;
}