Cod sursa(job #1184907)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 14 mai 2014 16:21:56
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 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], vis[Nmax];
int N, M, H, SQRT;
int A[18][Nmax];

void DFS( int nod, int d )
{
    depth[nod] = d;
    vis[nod] = 1;

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

int ancestor( int x, int cat )
{
    int lev = 17;

    while ( lev >= 0 )
    {
        if ( ( 1 << lev ) <= cat )
        {
            x = A[lev][x];
            cat -= ( 1 << lev );
        }

        lev--;
    }

    return x;
}

int lca( int x, int y )
{
    int st = 1, dr = N, m, gasit = -1;

    while ( st <= dr )
    {
        m = ( st + dr ) / 2;

        int a = ancestor( x, m );
        int b = ancestor( y, m );

        if ( a == b )
        {
            gasit = a;
            dr = m - 1;
        }
        else
        {
            st = m + 1;
        }
    }

    return gasit;
}

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

    f >> N >> M;

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

    for ( int i = 1; i <= N; ++i )
            A[0][i] = tata[i];

    for ( int i = 1; ( 1 << i ) <= N; ++i )
            for ( int j = 1; j <= N; ++j )
                    A[i][j] = A[i - 1][ A[i - 1][j] ];

    DFS( 1, 0 );

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

    return 0;
}