Pagini recente » Cod sursa (job #3131940) | Cod sursa (job #2161040) | Cod sursa (job #2743820) | Cod sursa (job #2044888) | Cod sursa (job #3227074)
#include<fstream>
#include<vector>
#include<queue>
using namespace std;
#define limit 17
ifstream cin("lca.in");
ofstream cout("lca.out");
vector<vector<int>> graph;
vector<vector<int>> parent;
vector<int> level;
void build(int root,int n) {
int u, v, nr;
for (nr = 1; nr < limit; nr++) {
queue<pair<int,int>> qp;
qp.push({ root,1 });
while (!qp.empty()) {
auto p = qp.front();
level[p.first] = p.second;
qp.pop();
for (auto v : graph[p.first]) {
parent[v][nr] = parent[parent[v][nr - 1]][nr - 1];
qp.push({ v,p.second + 1 });
}
}
}
}
int find(int u, int v) {
if (level[u] > level[v]) {
swap(u, v);
}
int nr = level[v] - level[u],i;
for (i = 0; i < limit; i++) {
if (nr & (1 << i)) {
v = parent[v][i];
}
}
if (u == v) {
return u;
}
nr = level[u];
for (i = limit - 1; i >= 0; i--) {
if (parent[u][i] != parent[v][i]) {
u = parent[u][i];
v = parent[v][i];
}
}
return parent[u][0];
}
int main() {
int i, j, nr, n, m, u, v;
cin >> n >> m;
level.resize(n);
parent = vector<vector<int>>(n, vector<int>(limit,0));
graph.resize(n);
for (v = 1; v < n; v++) {
cin >> u;
u--;
parent[v][0] = u;
graph[u].push_back(v);
}
build(0,n);
while (m--) {
cin >> u >> v;
u--;
v--;
cout << find(u, v) + 1 << "\n";
}
/*for (i = 0; i < n; i++) {
cout << i + 1 << " : ";
cout << level[i]<<" | ";
for (auto nr : parent[i]) {
cout << nr+1 << " ";
}
cout << "\n";
}*/
return 0;
}