Pagini recente » Cod sursa (job #1590031) | Cod sursa (job #550087) | Cod sursa (job #3125614) | Cod sursa (job #1447524) | Cod sursa (job #2854024)
#include<bits/stdc++.h>
using namespace std;
FILE *f=fopen("lca.in","r");
FILE *g=fopen("lca.out","w");
const int NMAX = 100004;
vector<int>G[NMAX];
int tata[NMAX];
int nivel[NMAX];
int N,M;
bitset<NMAX>viz;
void Read()
{
fscanf(f,"%d%d",&N,&M);
for(int i=2;i<=N;i++)
{
fscanf(f,"%d",&tata[i]);
/// adaugam muchie de la tata la fiu
G[tata[i]].push_back(i);
}
}
void Dfs(int nodCurent,int nivelCurent)
{
viz[nodCurent]=true;
nivel[nodCurent]=nivelCurent;
for(auto nodVecin : G[nodCurent])
{
if(viz[nodVecin])continue;
Dfs(nodVecin,nivelCurent+1);
}
//viz[nodCurent]=false;
}
int LCA(int x,int y)
{
/// cat timp nu au acelasi parinte
while(1)
{
/// astea sunt cazurile clare
/// nu ii corect sa dau return la final doar daca tata[x] == tata[y] pentru ca de exemplu daca am arborele 1-2-3-4
/// si verific 2-3 atunci LCA ii 2 nu tata[2]
if(x==y)return x;
if(tata[x]==tata[y])return tata[x];
if(tata[x] == y)return y;
if(tata[y] == x)return x;
/// daca parintii au acelasi nivel si nu este acelasi parinte atunci ambele merg un nivel mai sus
if(nivel[tata[x]] == nivel[tata[y]])
{
x=tata[x];y=tata[y];
}
/// daca tata[y] este mai sus ca tata[x] atunci mergem cu x mai sus
else if(nivel[tata[x]]>nivel[tata[y]])
{
x=tata[x];
}
/// daca tata[x] este mai sus ca tata[y] atunci mergem cu y mai sus
else y=tata[y];
}
}
void Solve()
{
Dfs(1,0);
int x,y;
for(int m=1;m<=M;m++)
{
fscanf(f,"%d%d",&x,&y);
fprintf(g,"%d\n",LCA(x,y));
}
}
int main()
{
Read();
Solve();
fclose(f);
fclose(g);
return 0;
}