Cod sursa(job #2512830)

Utilizator Stefan_PiscuPiscu Stefan Constantin Stefan_Piscu Data 21 decembrie 2019 18:42:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
#include <bits/stdc++.h>
using namespace std;

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

vector<int> heavy, head, ind, order, siz, level, fat;
vector<vector<int> >kids;
vector<vector<int>> vec;

void init(int n){
    vec.resize(n+1);
    ind.resize(n+1, 0);
    level.resize(n+1, 0);
    kids.resize(n+1);
    fat.resize(n+1, 0);
    siz.resize(n+1, 0);
    head.resize(n+1, 0);
    heavy.resize(n+1, 0);
}

bool viz[100002];

void dfs(int nod){
    viz[nod]=1;
    level[nod]=level[fat[nod]]+1;
    siz[nod]=1;
    for(auto i:vec[nod]){
        if(!viz[i]){
            fat[i]=nod;
            kids[nod].push_back(i);
            dfs(i);
            siz[nod]+=siz[i];
            if(siz[i]>siz[heavy[nod]]) heavy[nod]=i;
        }
    }
}

void decomp(int nod){
    if(!nod) return;
    ind[nod]=order.size();
    order.push_back(nod);
    if(heavy[nod]) head[heavy[nod]]=head[nod];
    decomp(heavy[nod]);
    for(auto i:kids[nod]){
        if(i!=heavy[nod]){
            head[i]=i;
            decomp(i);
        }
    }
}

int lca(int nod1, int nod2){
    if(level[nod1]>level[nod2]) swap(nod1, nod2);
    if(head[nod1]!=head[nod2]){
        if(level[head[nod1]]>level[head[nod2]]){
            return lca(fat[head[nod1]], nod2);
        }
        else{
            return lca(nod1, fat[head[nod2]]);
        }
    }
    return nod1;
}

int n, m;

int main()
{
    fin>>n>>m;
    init(n+1);
    for(int i=1;i<n;++i){
        int x;
        fin>>x;
        vec[x].push_back(i+1);
        vec[i+1].push_back(x);
    }
    dfs(1);
    decomp(1);
    for(int i=1;i<=m;++i){
        int u, v;
        fin>>u>>v;
        fout<<lca(u, v)<<"\n";
    }
    return 0;
}