Pagini recente » Cod sursa (job #1953048) | Istoria paginii utilizator/mirunagroza | Cod sursa (job #420966) | Statistici Botescu Stefan (Stefan_B) | Cod sursa (job #1510229)
#include <cstdio>
const int Nmax = 100000;
const int NIL = -1;
struct Edge {
int v;
int next;
};
Edge l[Nmax];
int adj[Nmax];
int heavy[Nmax];
int in[Nmax];
int d[Nmax];
int path[Nmax];
void addEdge(int u, int v, int pos) {
l[pos].v = v;
l[pos].next = adj[u];
adj[u] = pos;
}
void dfs(int u, int father) {
int best = -1;
int i, v;
heavy[u] = 1;
in[u] = u;
for (i = adj[u]; i != NIL; i = l[i].next) {
v = l[i].v;
d[v] = d[u] + 1;
dfs(v, u);
heavy[u] += heavy[v];
path[in[v]] = u;
if (best < heavy[v]) {
best = heavy[v];
in[u] = in[v];
}
}
}
int main(void) {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, m, i, u, v;
scanf("%d%d", &n, &m);
for (i = 0; i < n; i++) {
adj[i] = NIL;
}
for (i = 1; i < n; i++) {
scanf("%d", &u);
addEdge(u - 1, i, i - 1);
}
d[0] = 1;
path[in[0]] = 0;
dfs(0, -1);
for (i = 0; i < m; i++) {
scanf("%d%d", &u, &v);
u--; v--;
while (in[u] != in[v]) {
if (d[path[in[u]]] > d[path[in[v]]]) {
u = path[in[u]];
} else {
v = path[in[v]];
}
}
printf("%d\n", (d[u] < d[v] ? u : v) + 1);
}
fclose(stdin);
fclose(stdout);
return 0;
}