Pagini recente » Cod sursa (job #2047942) | Cod sursa (job #710726) | Cod sursa (job #3201812) | Cod sursa (job #3252569) | Cod sursa (job #3041384)
#include <iostream>
#include <vector>
#define MAXN 100000
#define MAX_LOG 20
using namespace std;
struct node{
bool visited;
int parent;
int lvl;
vector <int> neighbours;
};
node tree[MAXN];
int binaryLift[MAXN][MAX_LOG];
int n;
void dfs(int pos, int lvl) {
tree[pos].lvl = lvl;
tree[pos].visited = true;
for ( int v : tree[pos].neighbours ) {
if ( !tree[v].visited ) {
tree[v].parent = pos;
dfs(v, lvl + 1);
}
}
}
void buildBinaryLift() {
int i, i2;
for ( i = 0; i < n; i++ ) {
binaryLift[i][0] = tree[i].parent;
}
for ( i = 1; i < MAX_LOG; i++ ) {
for ( i2 = 0; i2 < n; i2++ ) {
binaryLift[i2][i] = binaryLift[binaryLift[i2][i - 1]][i - 1];
}
}
}
int lca(int a, int b) {
int i;
if ( tree[a].lvl < tree[b].lvl ) {
swap(a, b);
} ///tree[a].lvl = max
for ( i = MAX_LOG - 1; i >= 0; i-- ) {
if ( tree[a].lvl - (1 << i) >= tree[b].lvl ) {
a = binaryLift[a][i];
}
}
if ( a != b ) {
for ( i = MAX_LOG - 1; i >= 0; i-- ) {
if ( binaryLift[a][i] != binaryLift[b][i] ) {
a = binaryLift[a][i];
b = binaryLift[b][i];
}
}
a = binaryLift[a][0];
}
return a;
}
void addEdge(int a, int b) {
tree[a].neighbours.push_back(b);
tree[b].neighbours.push_back(a);
}
int main() {
FILE *fin, *fout;
fin = fopen("lca.in", "r");
fout = fopen("lca.out", "w");
int i, a, b, q;
fscanf(fin, "%d%d", &n, &q);
for ( i = 1; i < n; i++ ) {
fscanf(fin, "%d", &a);
a--;
addEdge(a, i);
}
dfs(0, 1);
buildBinaryLift();
while ( q-- ) {
fscanf(fin, "%d%d", &a, &b);
a--;
b--;
fprintf(fout, "%d\n", lca(a, b) + 1);
}
fclose(fin);
fclose(fout);
return 0;
}