Cod sursa(job #2214769)

Utilizator AndreiDumitrescuAndrei Dumitrescu AndreiDumitrescu Data 20 iunie 2018 00:56:16
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

int n, m;
int dp[30][100010], nivel[100010], tati[100010];
vector < vector<int>> v;


int creez_dinamica()
{
    for(int j = 1; j < 12; j++)
        for(int i = 1; i <= n; i++)
            dp[j][i] = dp[j - 1][dp[j - 1][i]];
}

int DFS(int nod, int nivel_actual)
{
    nivel[nod] = nivel_actual;
    for(int i = 0; i < v[nod].size(); i++)
        DFS(v[nod][i], nivel_actual + 1);
    return 0;
}

int query(int x, int y){

    while(nivel[x] > nivel[y])
        x = tati[x];
    while(nivel[y] > nivel[x])
        y = tati[y];
    if(x == y)
        return x;
    for(int bit = 12; bit >= 0; bit--)
    {
        if(bit != 0)
        {
            if(dp[bit][x] == dp[bit][y] && dp[bit - 1][x] != dp[bit - 1][y])
            {
                return query(dp[bit - 1][x], dp[bit - 1][y]);
            }
        }
        else
        {
            if(dp[bit][x] == dp[bit][y])
                return dp[bit][y];
        }

    }
}

int main()
{
    f >> n >> m;
    v.resize(n+1);
    int raspuns;
    for(int i = 2 ; i <= n ; i++)
    {
        f >> dp[0][i];
        tati[i] = dp[0][i];
        v[dp[0][i]].push_back(i);
    }
    creez_dinamica();
    DFS(1, 0);
    for(int i = 0; i < m; i++)
    {
        int x, y;
        f >> x >> y;
        raspuns = query(x, y) ;
        g << raspuns <<'\n';
    }
    return 0;
}