Cod sursa(job #1060832)

Utilizator classiusCobuz Andrei classius Data 18 decembrie 2013 20:09:27
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
// 8.12.2013
// Lowest Common Ancestor
// <O(N)> Pre-processing time
// <O(sqrt(N))> Query time
// I dived the tree into section, each section having sqrt(N) levels
//and for each node in section i, I keep it's immediate ancestor in section i-1
//when searching for the solution, I just go from section to section until I get
//the same ancestor

using namespace std;

#include<fstream>
#include<cmath>
#include<vector>
#include<algorithm>

ifstream cin("lca.in");
ofstream cout("lca.out");

const int MAXN=1000;

vector<int> v[MAXN]; // v[i][j] will point to the j-th son of node i
int A[MAXN]; // A[i] will point to the father of i;
int T[MAXN]; // here I will keep the ancestor from the previous section of each node
int L[MAXN]; // L[i] will have the level of node i
int k,H;

void dfs(int i,int dpt){
    if(dpt<k) T[i]=1; // I am in the first section
    else if(dpt%k==0) T[i]=A[i]; // I am at the beggining of a new section
    else T[i]=T[A[i]]; // I am in the middle of some section

    for(unsigned j=0;j<v[i].size();j++)
        dfs(v[i][j],dpt+1);
}

void dfsp(int i,int dpt){
    L[i]=dpt;
    H=max(dpt,H);

    for(unsigned j=0;j<v[i].size();j++)
        dfsp(v[i][j],dpt+1);
}

int main(){
    int N;

    cin>>N;


    for(int i=1;i<=N;i++){
        cin>>A[i];
        v[A[i]].push_back(i);
    }

    // I will assume that the root of the tree is 1, the program can be modified
    // to find the root of the tree if it is not 1
    // I do two dfs to see the debth of each node and process the ancestors

    dfsp(1,0); // An auxiliarry bfs to see the depth of the tree
    k=sqrt(H);
    dfs(1,0);

    // The Query Part
    int Q;
    cin>>Q;

    while(Q--){
        int x,y;
        cin>>x>>y;
        //I search for the section in which x and y have the same ancestor
        while(T[x]!=T[y]){
            if(L[x]<L[y])
                y=T[y];
            else x=T[x];
        }

        //I am in the section where x and y have the same ancestor so I search
        //For one lower or at the same level with that ancestor
        while(x!=y){
            if(L[x]<L[y])
                y=A[y];
            else x=A[x];
        }
        cout<<x<<'\n';
    }

    return 0;
}