Cod sursa(job #2032994)

Utilizator preda.andreiPreda Andrei preda.andrei Data 5 octombrie 2017 22:45:37
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <fstream>
#include <vector>

using namespace std;

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

using Tree = vector<Node>;

vector<int> FindAncestors(const Tree &t, int node)
{
  if (t[node].ancestors.empty()) {
    return vector<int>();
  }

  auto anc = t[node].ancestors[0];
  auto order = 0;
  vector<int> ancestors{anc};

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

void Dfs(Tree &t, int node)
{
  t[node].ancestors = FindAncestors(t, node);

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

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

int FindEarlyAncestor(const Tree &t, int node, int max_time)
{
  auto res = t[node].ancestors[0];
  for (const auto &anc : t[node].ancestors) {
    if (t[anc].time > max_time) {
      break;
    }
    res = anc;
  }
  return res;
}

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) {
    a = FindEarlyAncestor(t, a, t[b].time);
  }
  return a;
}

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

  int nodes, queries;
  fin >> nodes >> queries;

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

  Dfs(tree, 0);

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

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

  return 0;
}