Cod sursa(job #2605521)

Utilizator borscalinCalin-Stefan Georgescu borscalin Data 25 aprilie 2020 12:42:20
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.32 kb
#include <iostream>
#include <fstream>
#include <vector>

std::ifstream fin ( "lca.in" );
std::ofstream fout ( "lca.out" );

const int NMAX = 100000;

int father[1 + NMAX];
int entry[1 + NMAX], texit[1 + NMAX];
int t[20][1 + NMAX];
int timp;
std::vector <int> edges[1 + NMAX];

void dfs ( int node ) {

    entry[node] = ++timp;

    for ( int i = 0; i < edges[node].size(); ++i ) {
        int newNode = edges[node][i];
        dfs ( newNode );
    }
    
    texit[node] = ++timp;
}

bool common ( int x, int y ) {
    return  ( entry[x] <= entry[y] && texit[y] <= texit[x] );
}

int lca ( int x, int y ) {

    if ( common ( x, y ) )
        return x;
    
    int pas = 18;
    while ( pas >= 0 ) {
        int p = t[pas][x];
        if ( p != 0 && !common ( p, y ) ) 
            x = p;
        --pas;
    }
    return father[x];
}

int main() {

    int N, M;

    fin >> N >> M;

    for ( int i = 2; i <= N; ++i ) {
        fin >> father[i];
        t[0][i] = father[i];
        edges[father[i]].push_back ( i );
    }
    
    dfs ( 1 );

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

    for ( int i = 1; i <= M; ++i ) {
        int x, y;
        fin >> x >> y;
        fout << lca ( x, y ) << '\n';
    }

    fin.close();
    fout.close();

    return 0;
}