Cod sursa(job #2681723)

Utilizator etienAndrone Stefan etien Data 6 decembrie 2020 14:53:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,i,m;
vector<int>v[100001];
int nr[100001],t[100001],depth[100001];
int lant[100001];
bool viz[100001];
void dfs(int nod)
{
    for(auto q:v[nod])
    {
        if(q!=t[nod])
        {
            depth[q]=depth[nod]+1;
            dfs(q);
            nr[nod]+=nr[q];
        }
    }
    nr[nod]++;
}
void dfs2(int nod)
{
    if(lant[nod])
        return;
    int pop=-1;
    for(auto q:v[nod])
        if(q!=t[nod])
        {
            dfs2(q);
            if(pop<nr[q])
            {
                lant[nod]=lant[q];
                pop=nr[q];
            }
        }
}
int lca(int a,int b)
{
    while(lant[a]!=lant[b])
    {
        if(depth[lant[a]]<depth[lant[b]])
        {
            b=t[lant[b]];
        }
        else a=t[lant[a]];
    }
    if(depth[a]<depth[b])
        return a;
    return b;
}
int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++)
    {
        fin>>t[i];
        v[t[i]].push_back(i);
        v[i].push_back(t[i]);
    }
    dfs(1);
    for(int i=2;i<=n;i++)
        if(v[i].size()==1)
            lant[i]=i;
    dfs2(1);
    for(int i=2;i<=n;i++)
    {
        if(v[i].size()==1)
        {
            int nod=i;
            while(lant[t[nod]]==lant[i])
                nod=t[nod];
            int nod2=i;
            while(nod2!=t[nod])
            {
                viz[nod2]=true;
                lant[nod2]=nod;
                nod2=t[nod2];
            }
        }
    }
    for(int i=1;i<=m;i++)
    {
        int a,b;
        fin>>a>>b;
        fout<<lca(a,b)<<"\n";
    }
}