Cod sursa(job #2973955)

Utilizator gabriel.9619Gabriel Stefan Tita gabriel.9619 Data 2 februarie 2023 20:48:02
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.51 kb
#include <fstream>
#define MAX_LOG 18
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int vs[200001], vd[200001], stramos[18][100001], tata[100001];
int nr=0, n;
vector <int> l[100001];

void dfs(int nod)
{
    nr++;
    vs[nod]=nr;
    for(int i=0;i<l[nod].size();i++)
    {
        int vecin=l[nod][i];
        if(vecin!=tata[nod])
        {
            dfs(vecin);
        }
    }
    nr++;
    vd[nod]=nr;
}

int este_stramos(int x, int y)
{
    if(vs[x]<=vs[y]&&vd[y]<=vd[x])
    {
        return 1;
    }
    return 0;
}

void calculeaza_stramos()
{
    for(int nod=1; nod<=n; nod++)
    {
        stramos[0][nod]=tata[nod];
    }
    for(int p=1;p<MAX_LOG;p++)
    {
        for(int nod=1;nod<=n;nod++)
        {
            stramos[p][nod]=stramos[p-1][stramos[p-1][nod]];
        }
    }
}

int lca(int x, int y)
{
    if(este_stramos(x, y))
    {
        return x;
    }
    if(este_stramos(y, x))
    {
        return y;
    }
    for(int p=MAX_LOG-1; p>=0;p--)
    {
        int z=stramos[p][x];
        if(z!=0&&este_stramos(z, y)==0)
        {
            x=z;
        }
    }
    return stramos[0][x];
}

int main()
{
    int m, i, x, y;
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>tata[i];
        l[tata[i]].push_back(i);
        l[i].push_back(tata[i]);
    }
    dfs(1);
    calculeaza_stramos();
    for(i=1;i<=m;i++)
    {
        fin>>x>>y;
        fout<<lca(x, y)<<"\n";
    }
}