Cod sursa(job #391653)

Utilizator APOCALYPTODragos APOCALYPTO Data 6 februarie 2010 00:15:13
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.99 kb
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
vector<int> G[100005];

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); it++)
#define min(muie,tuie) (muie)<(tuie)?(muie):(tuie)
struct data{int lev;
int eul;
};
vector<data> E;
data aux;
int M[200005][20],lg[200005],H[100005],n,m;
ofstream fout("lca.out");
ifstream fin("lca.in");
void dfseuler(int nod,int niv)
{
  aux.lev=niv;
  aux.eul=nod;
  E.push_back(aux);
   H[nod]=E.size()-1;
  foreach(G[nod])/// nu mai punem conditia de vizitare datorita modului in care am construit listele de adiacenta
  {
      dfseuler(*it,niv+1);
     aux.lev=niv;
     aux.eul=nod;
     E.push_back(aux);
  }



}
void rmq()
{int i,j;
    lg[1]=0;
    for(i=2;i<=2*n;i++)
    lg[i]=lg[i/2]+1;
    for(i=1;i<=E.size()-1;i++)
      M[i][0]=i;
    for(j=1;j<=lg[E.size()-1];j++)
      for(i=1;i<=E.size()-(1<<i);i++)
      {if( E[M[i][j-1]].lev<E[M[i+(1<<(j-1))][j-1]].lev)
        M[i][j]= M[i][j-1];
        else
        M[i][j]= M[i+(1<<(j-1))][j-1];
      }


}

void citire()
{int x,i;

fin>>n>>m;

for(i=1;i<=n-1;i++)
   {fin>>x;
   G[x].push_back(i+1);}///adaugam doar fii deci daca trecem de la tata la fiu,
   /// tatal nu se va afla in lista fiului deci nu vom putea sa merge de la fiu la tata si nu vom avea ciclu infinit in cazul de fata


}

int main()
{ int i, tav,dra,high,low;
    citire();
    aux.lev=-1;
    aux.eul=-1;
    E.push_back(aux);
    dfseuler(1,0);
    rmq();
    for(i=1;i<=m;i++)
     {fin>>tav>>dra;
     if(H[tav]>H[dra])
      {high=H[tav];
      low=H[dra];
      }
      else
      {high=H[dra];
      low=H[tav];
      }

      if(E[M[low][lg[high-low+1]]].lev>E[M[high-(1<<lg[high-low+1])+1][lg[high-low+1]]].lev)
         fout<<E[M[high-(1<<lg[high-low+1])+1][lg[high-low+1]]].eul;
         else
         fout<<E[M[low][lg[high-low+1]]].eul;
     fout<<'\n';
     }
    fin.close();
    fout.close();
    return 0;
}