Pagini recente » Cod sursa (job #1488461) | Cod sursa (job #1391340) | Cod sursa (job #380088) | Cod sursa (job #2000495) | Cod sursa (job #1569364)
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <algorithm>
using std::vector;
using std::queue;
using std::swap;
const int MAX_N = 100000;
int N, M;
int father[1 + MAX_N];
vector<int> sons[1 + MAX_N];
struct Node;
struct Chain {
Node* top;
};
struct Node {
int index; //
Node *father; //
int weight; //
int depth; //
Chain *chain;
};
Node nodes[1 + MAX_N];
void dfs(int node) {
nodes[node].index = node;
nodes[node].weight = 1;
int maxWeightNode = 0;
for (int son : sons[node]) {
nodes[son].depth = nodes[node].depth + 1;
nodes[son].father = &nodes[node];
dfs(son);
nodes[node].weight += nodes[son].weight;
if (nodes[maxWeightNode].weight < nodes[son].weight) {
maxWeightNode = son;
}
}
if (maxWeightNode != 0) {
nodes[node].chain = nodes[maxWeightNode].chain;
} else {
nodes[node].chain = new Chain();
}
nodes[node].chain->top = &nodes[node];
}
void print(int node, int offset = 0) {
int i;
for (i = 0; i < offset; i++) {
printf(" ");
}
printf("%d: %d %d %d\n",
nodes[node].index,
nodes[node].depth,
nodes[node].weight,
nodes[node].chain->top->index);
for (int son : sons[node]) {
print(son, offset + 1);
}
}
int lca(int a, int b) {
while (nodes[a].chain != nodes[b].chain) {
if (nodes[a].chain->top->depth < nodes[b].chain->top->depth) {
swap(a, b);
}
a = nodes[a].chain->top->father->index;
}
if (nodes[a].depth < nodes[b].depth) {
return a;
} else {
return b;
}
}
int main() {
int i;
// freopen("lca.in", "r", stdin);
// freopen("lca.out", "w", stdout);
scanf("%d %d", &N, &M);
for (i = 2; i <= N; i++) {
scanf("%d", &father[i]);
sons[father[i]].push_back(i);
}
dfs(1);
print(1);
for (i = 1; i <= M; i++) {
int a, b;
scanf("%d %d", &a, &b);
printf("%d\n", lca(a, b));
}
return 0;
}