Cod sursa(job #2976270)

Utilizator andreibrosPeta Andrei Mathias andreibros Data 8 februarie 2023 19:39:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.73 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int NMAX=100005;

int A[NMAX][20];
int L[NMAX];
int tata[NMAX];
bool visited[NMAX];
vector <int> graf[NMAX];
int lca(int p, int q)
{
    // consideram nodul p nodul cu nivelul mai mare(mai jos)
    if(L[p]<L[q])
        swap(p,q);

    int lgp,lgq;

    for(lgp=0; (1<<lgp)<=L[p]; lgp++);
    lgp--;

    for(lgq=0; (1<<lgq)<=L[q]; lgq++);
    lgq--;

    // ma deplasez in sus pana cand nodul p ajunge la acelasi nivel cu nodul q
    for(int i=lgp; i>=0; i--)
    {
        if(A[p][i] && L[A[p][i]]>=L[q])
        {
            p=A[p][i];
        }
    }
   // cazul in care q este stramosul lui p
    if(p==q)
        return p;

    // sunt pe acelasi nivel si au un stramos comun
    for(int i=lgq; i>=0; i--)
    {
        if(A[p][i] && A[p][i]!=A[q][i])
        {
            p=A[p][i];
            q=A[q][i];
        }
    }
    return tata[p];
}

void dfs(int x)
{
    int y;
    visited[x]=1;
    for(unsigned int i=0; i<graf[x].size(); i++)
    {
        y=graf[x][i];
        if(visited[y]==0)
        {
            L[y]=L[x]+1;
            dfs(y);
        }
    }
}

int main()
{
    int n,m;
    in>>n>>m;

    for(int i=2; i<=n; i++)
    {
        in>>tata[i];
        graf[tata[i]].push_back(i);

    }
    dfs(1);

    for(int i=1; i<=n; i++)
        A[i][0]=tata[i];
    for(int i=1; i<=n; i++)
        for(int j=1; (1<<j)<=n; j++)
            if(A[i][j-1])
                A[i][j]=A[A[i][j-1]][j-1];
    int p,q;
    for(int i=1; i<=m; i++)
    {
        in>>p>>q;
        out<<lca(p,q)<<"\n";

    }




    return 0;
}