Cod sursa(job #2294183)

Utilizator AndreiDumitrescuAndrei Dumitrescu AndreiDumitrescu Data 2 decembrie 2018 00:25:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3 kb
#include <fstream>
//#include "algo.h"
#include <vector>
#include <queue>
using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");
 vector < vector<int>> graph;
 vector < pair<int, int>> queries;

 int tati[100010], nivel[100010], care_lant[100010], boss_lant[100010], viz[100010];
 vector < vector<int>> copii;
 vector < vector<int>> lant;

 int k = 0;

 int dfs(int nod, int nivel_actual)
 {
     nivel[nod] = nivel_actual;
     int ok = 0;
     for(int i = 0; i < copii[nod].size(); i++)
     {
         dfs(copii[nod][i], nivel_actual+1);
         ok = 1;
     }
     if(ok == 0)
     {
         lant[k].push_back(nod);
         care_lant[nod] = k;
         k++;
     }
     else
     {
         int maxim = 0, care;
         for(int i = 0; i < copii[nod].size(); i++)
         {
             if(lant[care_lant[copii[nod][i]]].size() > maxim)
             {
                 maxim = lant[care_lant[copii[nod][i]]].size();
                 care = care_lant[copii[nod][i]];
             }
         }
         lant[care].push_back(nod);
         care_lant[nod] = care;
         for(int i = 0; i < copii[nod].size(); i++)
         {
             if(care_lant[copii[nod][i]] != care)
             {
                 boss_lant[care_lant[copii[nod][i]]] = nod;
             }
         }
     }
     return 0;
 }

 int parcurgere(int x, int y)
 {
     if(care_lant[x] != care_lant[y])
     {
         if(nivel[boss_lant[care_lant[x]]] > nivel[boss_lant[care_lant[y]]])
         {
             if(boss_lant[care_lant[x]] == 0)
                 parcurgere(x, boss_lant[care_lant[y]]);
             else
                 parcurgere(boss_lant[care_lant[x]], y);

         }
         else
         {
             if(boss_lant[care_lant[y]] == 0)
                 parcurgere(boss_lant[care_lant[x]], y);
             else
                 parcurgere(x, boss_lant[care_lant[y]]);
         }
     }
     else
     {
         if(nivel[x] > nivel[y])
             return y;
         return x;
     }
 }

 void creez_tati(int nod, int anterior) {
    if(nod != 1) {
      tati[nod] = anterior;
      copii[anterior].push_back(nod);
    }
    viz[nod] = 1;
    for(int i = 0; i < graph[nod].size(); i++) {
      if(viz[graph[nod][i]] == 0) {
        creez_tati(graph[nod][i], nod);
      }
    }

 }

 void lca(const std::vector<std::vector<int>>& graph, const std::vector< std::pair<int, int> >& queries){
     copii.resize(graph.size() + 2);
     lant.resize(graph.size() + 2);
     //std::vector<int> answers(queries.size(), 0);
     creez_tati(1, 0);

     dfs(1, 0);
     for(int i = 0; i < queries.size(); i++) {
       g << parcurgere(queries[i].first, queries[i].second) << '\n';
       //cout << answers[i] << '\n';
     }


 }

int main() {
  int n, m;
  f >> n >> m;
  graph.resize(n + 1);
  queries.resize(m);
  for(int i = 2; i <= n; i++) {
    int x, y;
    f >> x;// >> y;
    graph[x].push_back(i);
    //graph[y].push_back(x);
  }
  for(int i = 0; i < m; i++) {
    int x, y;
    f >> x >> y;
    queries[i] = make_pair(x, y);
  }
  lca(graph, queries);
}