Cod sursa(job #1569364)

Utilizator usermeBogdan Cretu userme Data 15 ianuarie 2016 14:20:51
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <stdio.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <algorithm>

using std::vector;
using std::queue;
using std::swap;

const int MAX_N = 100000;

int N, M;

int father[1 + MAX_N];
vector<int> sons[1 + MAX_N];

struct Node;

struct Chain {
  Node* top;
};

struct Node {
  int index; //
  Node *father; //
  int weight; //
  int depth; //
  Chain *chain;
};

Node nodes[1 + MAX_N];

void dfs(int node) {
  nodes[node].index = node;
  nodes[node].weight = 1;
  int maxWeightNode = 0;
  for (int son : sons[node]) {
    nodes[son].depth = nodes[node].depth + 1;
    nodes[son].father = &nodes[node];
    dfs(son);
    nodes[node].weight += nodes[son].weight;
    if (nodes[maxWeightNode].weight < nodes[son].weight) {
      maxWeightNode = son;
    }
  }
  if (maxWeightNode != 0) {
    nodes[node].chain = nodes[maxWeightNode].chain;
  } else {
    nodes[node].chain = new Chain();
  }
  nodes[node].chain->top = &nodes[node];
}

void print(int node, int offset = 0) {
  int i;
  for (i = 0; i < offset; i++) {
    printf("  ");
  }
  printf("%d: %d %d %d\n",
      nodes[node].index,
      nodes[node].depth,
      nodes[node].weight,
      nodes[node].chain->top->index);
  for (int son : sons[node]) {
    print(son, offset + 1);
  }
}

int lca(int a, int b) {
  while (nodes[a].chain != nodes[b].chain) {
    if (nodes[a].chain->top->depth < nodes[b].chain->top->depth) {
      swap(a, b);
    }
    a = nodes[a].chain->top->father->index;
  }
  if (nodes[a].depth < nodes[b].depth) {
    return a;
  } else {
    return b;
  }
}

int main() {
  int i;
//  freopen("lca.in", "r", stdin);
//  freopen("lca.out", "w", stdout);
  scanf("%d %d", &N, &M);
  for (i = 2; i <= N; i++) {
    scanf("%d", &father[i]);
    sons[father[i]].push_back(i);
  }
  dfs(1);
  print(1);

  for (i = 1; i <= M; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    printf("%d\n", lca(a, b));
  }
  return 0;
}