Cod sursa(job #3261513)

Utilizator AndreiNicolaescuEric Paturan AndreiNicolaescu Data 6 decembrie 2024 16:25:15
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int Lmax = 16;
vector<vector<int>> graf, anc;
vector<int> viz, tin, tout;
int n, m, x, y, time = 0;
void dfs(int node)
{
    viz[node] = 1;
    tin[node] = ++time;
    for(auto next:graf[node])
        if(!viz[next])
            dfs(next);
    tout[node] = ++time;
}
void binarylifting()
{
    for(int l=1; l<Lmax; l++)
        for(int node = 1; node <= n; node++)
            anc[l][node] = anc[l-1][anc[l-1][node]];
}
bool isanc(int node1, int node2)
{
    return tin[node1] <= tin[node2] && tout[node1] >= tout[node2];
}
int lca(int node1, int node2)
{
    if(isanc(node1, node2))
        return node1;

    if(isanc(node2, node1))
        return node2;

    for(int l=Lmax-1; l>=0; l--)
        if(anc[l][node1] && !isanc(anc[l][node1], node2))
            node1 = anc[l][node1];
    return anc[0][node1];
}
int main()
{
    cin >> n >> m;

    graf.resize(n+1, vector<int>());
    anc.assign(Lmax, vector<int>(n+1, 0));
    viz.resize(n+1);
    tin.resize(n+1);
    tout.resize(n+1);
    for(int i=2; i<=n; i++)
    {
        cin >> anc[0][i];
        graf[anc[0][i]].push_back(i);
        graf[i].push_back(anc[0][i]);
    }
    dfs(1);
    binarylifting();

    while(m--)
    {
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}