Pagini recente » Cod sursa (job #484929) | Cod sursa (job #971335) | Cod sursa (job #1475730) | Cod sursa (job #1073532) | Cod sursa (job #1060832)
// 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;
}