Cod sursa(job #2880586)

Utilizator StanCatalinStanCatalin StanCatalin Data 29 martie 2022 21:33:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <iostream>
#include <vector>
#include <fstream>

using namespace std;

ifstream in("lca.in");
ofstream out("lca.out");

const int dim = 1e5 + 5;

int n, m;
vector<int> vec[dim];
int hp_id[dim], first[dim], last[dim], ordin[dim], urmator[dim], nivel[dim], parinte[dim], nivel_initial[dim];

void compute_hp(int nod, int &k, int parent) {

    hp_id[nod] = k;
    last[k] = nod;

    if (vec[nod].size() == 1 && nod != 1) {
        return;
    }

    int maxi = -1;
    for (auto y:vec[nod]) {
        if (y != parent) maxi = y;
    }

    for (auto y:vec[nod]) {
        if (y != parent) {
            if (ordin[y] > ordin[maxi]) {
                maxi = y;
            }
        }
    }
    urmator[nod] = maxi;
    compute_hp(maxi, k, nod);

    for (auto y:vec[nod]) {
        if (y != parent) {
            if (y != maxi) {
                first[k+1] = y;
                last[k+1] = y;
                compute_hp(y, ++k, nod);
            }
        }
    }
}

void hp_level(int nod, int parent) {
    if (first[hp_id[nod]] == nod) {
        if (nod == 1) {
            nivel[hp_id[nod]] = 0;
        } else {
            nivel[hp_id[nod]] = 1 + nivel[hp_id[parinte[nod]]];
        }
    }
    for (auto y:vec[nod]) {
        if (y != parent) {
            hp_level(y, nod);
        }
    }
}

void DFS(int nod, int parent) {
    nivel_initial[nod] = 1 + nivel_initial[parent];
    parinte[nod] = parent;
    for (auto y:vec[nod]) {
        if (y != parent) {
            DFS(y, nod);
            ordin[nod] += ordin[y];
        }
    }
}

int lca(int x, int y) {
    ///cout << x << " " << y << "\n";
    while (hp_id[x] != hp_id[y]) {
        if (nivel[hp_id[x]] > nivel[hp_id[y]]) {
            x = parinte[first[hp_id[x]]];
        } else {
            y = parinte[first[hp_id[y]]];
        }
    }
   /// cout << x << " " << y << "\n";
    if (nivel_initial[x] >= nivel_initial[y]) {
        return y;
    } else {
        return x;
    }
}

int main() {
    in >> n >> m;
    int aux;
    first[0] = 1;
    for (int i = 2; i <= n; ++i) {
        ordin[i] = 1;
        in >> aux;
        vec[aux].push_back(i);
        vec[i].push_back(aux);
    }
    int x, y;
    int k = 0;
    DFS(1, 0);
    compute_hp(1, k, 0);
    hp_level(1, 0);

   while (m--) {
        in >> x >> y;
        out << lca(x, y) << "\n";
        ///cout << "\n\n\n\n";
   }
    return 0;
}