Cod sursa(job #1193410)

Utilizator teoionescuIonescu Teodor teoionescu Data 31 mai 2014 18:08:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.35 kb
#include<fstream>
#include<vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int Nmax = 100001;
vector<int> G[Nmax];
int T[Nmax],L[Nmax],H[Nmax];
int ChainFat[Nmax],PartOfChain[Nmax],NumChains;
int N,M;
int Dfs(int x,int lev){
    L[x]=lev;
    H[x]=1;
    for(vector<int>::iterator it=G[x].begin();it!=G[x].end();++it){
        H[x]+=Dfs(*it,lev+1);
    }
    return H[x];
}
void DfsChain(int x,int wh){
    PartOfChain[x]=wh;
    int best=0,ch;
    for(vector<int>::iterator it=G[x].begin();it!=G[x].end();++it){
        if(H[*it]>best) best=H[*it],ch=*it;
    }
    for(vector<int>::iterator it=G[x].begin();it!=G[x].end();++it){
        if(*it==ch) DfsChain(*it,wh);
        else{
            ChainFat[++NumChains]=x;
            DfsChain(*it,NumChains);
        }
    }
}
int lca(int x,int y){
    while(PartOfChain[x]!=PartOfChain[y]){
        if(L[ChainFat[PartOfChain[x]]]>L[ChainFat[PartOfChain[y]]])
            x=ChainFat[PartOfChain[x]];
        else y=ChainFat[PartOfChain[y]];
    }
    if(L[x]<L[y]) return x;
    return y;
}
int main(){
    in>>N>>M;
    for(int i=2;i<=N;i++){
        in>>T[i];
        G[T[i]].push_back(i);
    }
    Dfs(1,1);
    DfsChain(1,++NumChains);
    int x,y;
    for(;M;--M){
        in>>x>>y;
        out<<lca(x,y)<<'\n';
    }
    return 0;
}