Cod sursa(job #2909888)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 16 iunie 2022 15:41:07
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
//
// Created by mihai145 on 16.06.2022.
//

#include <fstream>
#include <vector>

std::ifstream cin("lca.in");
std::ofstream cout("lca.out");

const int NMAX = 1e5;

int n, m;
std::vector<int> g[NMAX + 2];
int p[NMAX + 2], lvl[NMAX + 2], w[NMAX + 2], heavy_head[NMAX + 2];

void dfs(int node) {
    w[node] = 1;

    for(int son : g[node]) {
        p[son] = node;
        lvl[son] = lvl[node] + 1;
        dfs(son);
        w[node] += w[son];
    }
}

void dfs_heavy(int node) {
    if(g[node].size() == 0) {
        return;
    }

    int heavy_son = g[node][0];
    for(int son : g[node]) {
        if(w[son] > w[heavy_son]) {
            heavy_son = son;
        }
    }

    heavy_head[heavy_son] = heavy_head[node];

    for(int son : g[node]) {
        dfs_heavy(son);
    }
}

int lca(int x, int y) {
    while(heavy_head[x] != heavy_head[y]) {
        if(lvl[heavy_head[x]] > lvl[heavy_head[y]]) {
            x = p[heavy_head[x]];
        } else {
            y = p[heavy_head[y]];
        }
    }

    if(lvl[x] < lvl[y]) {
        return x;
    }
    return y;
}

int main() {
    cin >> n >> m;

    for(int i = 2; i <= n; i++) {
        int t; cin >> t;
        g[t].push_back(i);
    }

    p[1] = -1;
    dfs(1);

    for(int i = 1; i <= n; i++) {
        heavy_head[i] = i;
    }
    dfs_heavy(1);

    for(int i = 1; i <= m; i++) {
        int x, y; cin >> x >> y;
        cout << lca(x, y) << '\n';
    }

    return 0;
}