Cod sursa(job #2093450)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 23 decembrie 2017 18:26:14
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include <fstream>
#include <vector>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

class Hpd {
public:

  Hpd(int n, int m) { 
    this -> n = n;
    this -> m = m;
    _chain.resize(n + 1);
    _level.resize(n + 1);
    _tata.resize(n + 1);
    _chain_of.resize(n + 1);
    _weight.resize(n + 1);
    _gr.resize(n + 1);
    max_chain = 0;

    for (int i = 2; i <= n; i ++) {
      cin >> _tata[i];
      _gr[_tata[i]].push_back(i);
    }

    _Init(1, 1);
  }

  void Solve() {
    
    int x, y;
    for (int i = 1; i <= this -> m; i ++) {
      cin >> x >> y;

      while (_chain_of[x] != _chain_of[y]) {

        int clx = _chain[_chain_of[x]].back();
        int cly = _chain[_chain_of[y]].back();
        if (_level[clx] >= _level[cly]) {
          x = _tata[clx];
        }
        else {
          y = _tata[cly];
        }
      }

      if (_level[x] <= _level[y]) {
        cout << x << '\n';
      }
      else {
        cout << y << '\n';
      }
    }
  }

private:

  int n, m, max_chain;
  vector < int > _level, _chain_of, _weight, _tata;
  vector < vector < int > > _chain, _gr;
  
  void _Init(int cur_node, int cur_level) {
    
    _level[cur_node] = cur_level;
    if (_gr[cur_node].size() == 0) {
      _chain[++ max_chain].push_back(cur_node);
      _chain_of[cur_node] = max_chain;
      _weight[max_chain] = 1;
      return;
    }
  
    int best = -1, max_w = -1;
    for (auto x : _gr[cur_node]) {
      _Init(x, cur_level + 1);
      if (_weight[_chain_of[x]] > max_w) {
        best = x;
        max_w = _weight[_chain_of[x]];
      }
    }

    _chain[_chain_of[best]].push_back(cur_node);
    _chain_of[cur_node] = _chain_of[best];
    _weight[_chain_of[best]] += 1;
    for (auto x : _gr[cur_node]) {
      if (x == best) {
        continue;
      }
      _weight[_chain_of[best]] += _weight[_chain_of[x]];
    }
  }
};
int main() {
  
  int n, m;
  cin >> n >> m;
  Hpd *H = new Hpd(n, m);
  H -> Solve();
}