Cod sursa(job #2016000)

Utilizator preda.andreiPreda Andrei preda.andrei Data 28 august 2017 13:43:12
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.5 kb
#include <fstream>
#include <vector>

using namespace std;

struct Node
{
  int time = 0;
  vector<int> sons;
  vector<int> ancestors;
};

using Tree = vector<Node>;

void Dfs(Tree &t, int node)
{
  if (!t[node].ancestors.empty()) {
    int father = t[node].ancestors[0];
    int order = 0;

    while (order < (int)t[father].ancestors.size()) {
      int anc = t[father].ancestors[order];
      t[node].ancestors.push_back(anc);
      father = anc;
      order += 1;
    }
  }

  for (const auto &son : t[node].sons) {
    Dfs(t, son);
  }

  static int time = 0;
  t[node].time = ++time;
}

int FindLca(const Tree &t, int a, int b)
{
  if (t[a].time > t[b].time) {
    swap(a, b);
  }

  while (t[a].time < t[b].time) {
    if (t[a].ancestors.size() == 1) {
      a = t[a].ancestors[0];
    }

    for (size_t i = 1; i < t[a].ancestors.size(); ++i) {
      int anc = t[a].ancestors[i];
      if (t[anc].time > t[b].time) {
        a = t[a].ancestors[i - 1];
        break;
      } else if (i + 1 == t[a].ancestors.size()) {
        a = t[a].ancestors.back();
      }
    }
  }
  return a;
}

int main()
{
  ifstream fin("lca.in");
  ofstream fout("lca.out");

  int nodes, q;
  fin >> nodes >> q;

  Tree tree(nodes);
  for (int i = 1; i < nodes; ++i) {
    int father;
    fin >> father;
    tree[i].ancestors.push_back(father - 1);
    tree[father - 1].sons.push_back(i);
  }

  Dfs(tree, 0);

  while (q--) {
    int a, b;
    fin >> a >> b;

    auto res = FindLca(tree, a - 1, b - 1);
    fout << res + 1 << "\n";
  }
  return 0;
}