Pagini recente » Cod sursa (job #1688959) | Cod sursa (job #2948464) | Cod sursa (job #2497316) | Cod sursa (job #409918) | Cod sursa (job #3300593)
#include <bits/stdc++.h>
#define cin ci
#define cout co
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int Lmax = 21;
int n, m, x, y;
vector<vector<int>> graf, anc;
vector<int> dist, viz;
void dfs(int node, int par, int h)
{
dist[node] = h;
for(auto next:graf[node])
if(next != par)
dfs(next, node, h + 1);
}
void binarylifting()
{
for(int i=1; i<Lmax; i++)
for(int node=1; node<=n; node++)
anc[i][node] = anc[i-1][anc[i-1][node]];
}
int findanc(int node, int nmb)
{
int ans = 0;
for(int l=Lmax - 1; l>=0; l--)
if(nmb & (1 << l))
node = anc[l][node];
return node;
}
int lca(int node1, int node2)
{
if(dist[node1] < dist[node2])
swap(node1, node2);
node1 = findanc(node1, dist[node1] - dist[node2]);
if(node1 == node2)
return node1;
for(int l=Lmax - 1; l>=0; l--)
if(anc[l][node1] != anc[l][node2])
{
node1 = anc[l][node1];
node2 = anc[l][node2];
}
return anc[0][node1];
}
int main()
{
cin >> n >> m;
graf.assign(n+1, vector<int>());
anc.resize(Lmax, vector<int>(n+1, 0));
dist.resize(n+1);
viz.resize(n+1);
for(int i=2; i<=n; i++)
{
cin >> x;
anc[0][i] = x;
graf[x].push_back(i);
graf[i].push_back(x);
}
dfs(1, -1, 0);
for(int i=1; i<=m; i++)
{
cin >> x >> y;
cout << lca(x, y) << '\n';
}
return 0;
}