Cod sursa(job #2028201)

Utilizator LucaSeriSeritan Luca LucaSeri Data 27 septembrie 2017 12:54:52
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 kb
#include <bits/stdc++.h>
//SOLUTIA 3 - HEAVY PATH SIMPLU
using namespace std;

const int Max = 100010;

ifstream f("lca.in");
ofstream g("lca.out");

vector <int> lant[Max];
vector <int> graf[Max];

int lantdenod[Max], nivel[Max], tata[Max], sub[Max], poz[Max], lanturi = 0;

void dfs(int node, int boss, int lvl){
    nivel[node] = lvl;
    sub[node] = 1;
    for(int x : graf[node]){
        if(x != boss){
            tata[x] = node;
            dfs(x, node, lvl+1);
            sub[node] += sub[x];
        }
    }
    if(graf[node].size() == 1 && node != 1){
        ++lanturi;
        lant[lanturi].push_back(0);
        lant[lanturi].push_back(node);
        lantdenod[node] = lanturi;
        poz[node] = 1;
        return;
    }

    int best = 0;
    for(int x : graf[node]){
        if(x != boss && sub[x] > sub[best]){
            best = x;
        }
    }

    lantdenod[node] = lantdenod[best];
    lant[lantdenod[best]].push_back(node);
    poz[node] = lant[lantdenod[node]].size()-1;
}

int solve(int x, int y){
    int lx = lantdenod[x];
    int ly = lantdenod[y];

    while(lx != ly){
        if(nivel[lant[lx][1]] < nivel[lant[ly][1]]) swap(x, y);
        x = tata[lant[lantdenod[x]][1]];
        lx = lantdenod[x];
        ly = lantdenod[y];
    }

    if(poz[x] < poz[y]) return x;
    return y;
}

int main(){
    int n, m;
    f >> n >> m;
    for(int i = 2; i <= n; ++ i){
         f >> tata[i];
         graf[i].push_back(tata[i]);
         graf[tata[i]].push_back(i);
    }
    dfs(1, 0, 0);

    for(int i = 1; i <= lanturi; ++ i){
        reverse(lant[i].begin()+1, lant[i].end());
    }
    for(int i = 1; i <= n; ++ i){
        poz[i] = lant[lantdenod[i]].size()-poz[i];
    }
    for(int i = 1; i <= m; ++ i){
        int x, y;
        f >> x >> y;
        g << solve(x, y) << '\n';
    }
}