Cod sursa(job #1403404)

Utilizator BLz0rDospra Cristian BLz0r Data 27 martie 2015 11:44:43
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.46 kb
#include <cstdio>
#include <vector>
#include <bitset>
#include <algorithm>
using namespace std;

#define Nmax 32002
#define Lmax 16
#define pb push_back

FILE *f = fopen ( "concurs.in", "r" );
FILE *g = fopen ( "concurs.out", "w" );

int Rmq[Lmax][Nmax<<1], Lg[Nmax<<1], First[Nmax], Eu[Nmax<<1], Niv[Nmax<<1], points[Nmax], N, M, K;
vector < int > G[Nmax];
bitset < Nmax > sef;

void DFS ( int nod, int niv ){
    vector < int > :: iterator it;

    Eu[++K] = nod;
    Niv[K] = niv;
    First[nod] = K;

    for ( it = G[nod].begin(); it < G[nod].end(); ++it ){
            DFS ( *it, niv + 1 );
            Eu[++K] = nod;
            Niv[K] = niv;
    }

}

void RMQ (){

    for ( int i = 2; i <= K; ++i )
        Lg[i] = Lg[i>>1] + 1;

    for ( int i = 1; i <= K; ++i )
        Rmq[0][i] = i;

    for ( int i = 1; ( 1 << i ) < K; ++i ){
        for ( int j = 1; j <= K - ( 1 << i ); ++j ){
            int t = ( 1 << ( i - 1 ) );
            Rmq[i][j] = Rmq[i-1][j];
            if ( Niv[Rmq[i][j]] > Niv[Rmq[i-1][j+t]] )
                Rmq[i][j] = Rmq[i-1][j+t];
        }
    }
}

int LCA ( int x, int y ){
        if ( x > y )
            swap ( x, y );

        int dif = y - x + 1;
        int k = Lg[dif];
        int t = dif - ( 1 << k );
        int sol = Rmq[k][x];

        if ( Niv[sol] > Niv[Rmq[k][x+t]] )
            sol = Rmq[k][x+t];

        return points[Eu[sol]];
}

int main(){
    int x, y, rad, maxs = -1, solx, soly;

    fscanf ( f, "%d%d", &N, &M );

    for ( int i = 1; i <= N; ++i )
        fscanf ( f, "%d", &points[i] );

    for ( int i = 1; i < N; ++i ){
        fscanf ( f, "%d%d", &x, &y );
        G[x].pb ( y );
        sef[y] = 1;
    }

    for ( int i = 1; i <= N; ++i )
        if ( !sef[i] ){
            rad = i;
            break;
        }

    DFS ( rad, 0 );
    RMQ ();

    for ( int i = 1; i <= M; ++i ){
        fscanf ( f, "%d%d", &x, &y );
        int t = LCA ( First[x], First[y] );
        if ( t > maxs ){
            maxs = t;
            solx = x;
            soly = y;

        }
        else{
            if ( t == maxs ){
                if ( solx > x ){
                    solx = x;
                    soly = y;
                }
                else
                    if ( solx == x && soly > y )
                        soly = y;

            }
        }
    }

    fprintf ( g, "%d %d %d", maxs, solx, soly );

    return 0;
}