Pagini recente » Cod sursa (job #1798410) | Cod sursa (job #1702702) | Cod sursa (job #2381310) | Cod sursa (job #2347363) | Cod sursa (job #2976270)
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX=100005;
int A[NMAX][20];
int L[NMAX];
int tata[NMAX];
bool visited[NMAX];
vector <int> graf[NMAX];
int lca(int p, int q)
{
// consideram nodul p nodul cu nivelul mai mare(mai jos)
if(L[p]<L[q])
swap(p,q);
int lgp,lgq;
for(lgp=0; (1<<lgp)<=L[p]; lgp++);
lgp--;
for(lgq=0; (1<<lgq)<=L[q]; lgq++);
lgq--;
// ma deplasez in sus pana cand nodul p ajunge la acelasi nivel cu nodul q
for(int i=lgp; i>=0; i--)
{
if(A[p][i] && L[A[p][i]]>=L[q])
{
p=A[p][i];
}
}
// cazul in care q este stramosul lui p
if(p==q)
return p;
// sunt pe acelasi nivel si au un stramos comun
for(int i=lgq; i>=0; i--)
{
if(A[p][i] && A[p][i]!=A[q][i])
{
p=A[p][i];
q=A[q][i];
}
}
return tata[p];
}
void dfs(int x)
{
int y;
visited[x]=1;
for(unsigned int i=0; i<graf[x].size(); i++)
{
y=graf[x][i];
if(visited[y]==0)
{
L[y]=L[x]+1;
dfs(y);
}
}
}
int main()
{
int n,m;
in>>n>>m;
for(int i=2; i<=n; i++)
{
in>>tata[i];
graf[tata[i]].push_back(i);
}
dfs(1);
for(int i=1; i<=n; i++)
A[i][0]=tata[i];
for(int i=1; i<=n; i++)
for(int j=1; (1<<j)<=n; j++)
if(A[i][j-1])
A[i][j]=A[A[i][j-1]][j-1];
int p,q;
for(int i=1; i<=m; i++)
{
in>>p>>q;
out<<lca(p,q)<<"\n";
}
return 0;
}