Cod sursa(job #461850)

Utilizator BitOneSAlexandru BitOne Data 8 iunie 2010 20:01:08
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.65 kb
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iterator>
#define Nmax 100011

/*
 *
 */
using namespace std;
ifstream in;
ofstream out;
bool was[Nmax];
int f[Nmax], r[Nmax], anc[Nmax], ans[Nmax];
vector< int > G[Nmax];
vector< pair< int, int > > P[Nmax];
inline int find( int x )
{
    int y, z;
    for( y=x; y != f[y]; y=f[y] );
    while( x != f[x] )
    {
        z=f[x];
        f[x]=y;
        x=z;
    }
    return y;
}
inline void Unite( int x, int y )
{
    if( r[x] == r[y] )
    {
        if( x != y )
            f[y]=x;
        ++r[y];
    }
    else r[x]=r[y]=( r[x] <= r[y] ? r[x] : r[y] );
}
inline void MakeSet( int x )
{
    f[x]=x;
    r[x]=1;
    anc[x]=x;
}
inline void DFS( int x )
{
    MakeSet(x);
    vector< int >::const_iterator it=G[x].begin(), iend=G[x].end();
    for( ; it < iend; ++it )
    {
        DFS(*it);
        int tx=find(x), ty=find(*it);
        Unite( tx, ty );
        anc[tx]=x;
    }
    was[x]=true;
    for( vector< pair< int, int > >::const_iterator it=P[x].begin(), iend=P[x].end(); it < iend; ++it )
        if( was[it->first] )
           ans[it->second] =anc[find(it->first )];
}
int main( void )
{
    int N, M, i, x, y;
    in.open( "lca.in" );
    in>>N>>M;
    for( i=2; i <= N; ++i )
    {
        in>>x;
        G[x].push_back(i);
    }
    for( i=1; i <= M; ++i )
    {
        in>>x>>y;
        P[x].push_back( pair< int, int >( y, i ) );
        P[y].push_back( pair< int, int >( x, i ) );
    }
    DFS(1);
    out.open( "lca.out" );
    copy( ans+1, ans+M+1, ostream_iterator<int>( out, "\n" ) );
    return EXIT_SUCCESS;
}