Cod sursa(job #2214772)

Utilizator AndreiDumitrescuAndrei Dumitrescu AndreiDumitrescu Data 20 iunie 2018 01:21:01
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.64 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

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

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


int creez_dinamica()
{
    for(int j = 1; j < 21; 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] = 0;
  queue<int> q;
  q.push(nod);
  while(!q.empty())
  {
      nod = q.front();
      q.pop();
      for(int i = 0; i < v[nod].size(); i++)
      {
          q.push(v[nod][i]);
          nivel[v[nod][i]] = nivel[nod] + 1;
      }
  }

}

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 = 21; 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+10);
    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;
}