Cod sursa(job #1510238)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 24 octombrie 2015 18:45:39
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.42 kb
#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 best = 0;
    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);
        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;
    dfs(0);

    for (i = 0; i < m; i++) {
        scanf("%d%d", &u, &v);
        u--; v--;
        while ((in[u] != in[v]) && (u && 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;
}