Pagini recente » Cod sursa (job #213859) | Cod sursa (job #543667) | Cod sursa (job #992729) | Istoria paginii runda/budescu/clasament | Cod sursa (job #3232314)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAXN 100001
typedef struct {
int *data;
int size;
int capacity;
} Vector;
void initVector(Vector *v, int capacity) {
v->data = (int *)malloc(capacity * sizeof(int));
v->size = 0;
v->capacity = capacity;
}
void pushBack(Vector *v, int value) {
if (v->size == v->capacity) {
v->capacity *= 2;
v->data = (int *)realloc(v->data, v->capacity * sizeof(int));
}
v->data[v->size++] = value;
}
typedef struct {
int *first;
int *euler;
int *height;
int **rmq;
int eulerIndex;
int n;
} LCA;
void dfs(LCA *lca, Vector *tree, int node, int h) {
lca->first[node] = lca->eulerIndex;
lca->height[lca->eulerIndex] = h;
lca->euler[lca->eulerIndex++] = node;
for (int i = 0; i < tree[node].size; ++i) {
int nextNode = tree[node].data[i];
if (lca->first[nextNode] == -1) {
dfs(lca, tree, nextNode, h + 1);
lca->euler[lca->eulerIndex] = node;
lca->height[lca->eulerIndex++] = h;
}
}
}
void buildRMQ(LCA *lca) {
int m = 2 * lca->n - 1;
int logm = (int)log2(m) + 1;
lca->rmq = (int **)malloc(m * sizeof(int *));
for (int i = 0; i < m; ++i) {
lca->rmq[i] = (int *)malloc(logm * sizeof(int));
lca->rmq[i][0] = i;
}
for (int j = 1; (1 << j) <= m; ++j) {
for (int i = 0; i + (1 << j) - 1 < m; ++i) {
int first = lca->rmq[i][j - 1];
int second = lca->rmq[i + (1 << (j - 1))][j - 1];
lca->rmq[i][j] = (lca->height[first] < lca->height[second]) ? first : second;
}
}
}
int queryRMQ(LCA *lca, int left, int right) {
int length = right - left + 1;
int logLength = (int)log2(length);
int first = lca->rmq[left][logLength];
int second = lca->rmq[right - (1 << logLength) + 1][logLength];
return (lca->height[first] < lca->height[second]) ? first : second;
}
int findLCA(LCA *lca, int u, int v) {
if (lca->first[u] > lca->first[v]) {
int temp = u;
u = v;
v = temp;
}
int left = lca->first[u];
int right = lca->first[v];
int index = queryRMQ(lca, left, right);
return lca->euler[index];
}
int main() {
FILE *in = fopen("lca.in", "r");
FILE *out = fopen("lca.out", "w");
int n, m;
fscanf(in, "%d %d", &n, &m);
Vector tree[MAXN];
for (int i = 1; i <= n; ++i) {
initVector(&tree[i], 2);
}
for (int i = 2; i <= n; ++i) {
int parent;
fscanf(in, "%d", &parent);
pushBack(&tree[parent], i);
}
LCA lca;
lca.n = n;
lca.euler = (int *)malloc(2 * n * sizeof(int));
lca.first = (int *)malloc((n + 1) * sizeof(int));
lca.height = (int *)malloc(2 * n * sizeof(int));
for (int i = 1; i <= n; ++i) {
lca.first[i] = -1;
}
lca.eulerIndex = 0;
dfs(&lca, tree, 1, 0);
buildRMQ(&lca);
for (int i = 0; i < m; ++i) {
int u, v;
fscanf(in, "%d %d", &u, &v);
int lcaNode = findLCA(&lca, u, v);
fprintf(out, "%d\n", lcaNode);
}
fclose(in);
fclose(out);
// Free allocated memory
free(lca.euler);
free(lca.first);
free(lca.height);
for (int i = 0; i < 2 * n - 1; ++i) {
free(lca.rmq[i]);
}
free(lca.rmq);
for (int i = 1; i <= n; ++i) {
free(tree[i].data);
}
return 0;
}