Cod sursa(job #1665667)

Utilizator papinubPapa Victor papinub Data 27 martie 2016 11:11:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.36 kb
#include <cstdio>
#include <vector>

using std::vector;

const int MAX_N = 100000;

struct Nod;
struct Lant;

struct Nod {
  int index;
  vector<Nod*> vecini;
  int adancime;
  int greutate;
  Lant* lant;
};

struct Lant {
  Nod* tata;
  vector<Nod*> noduri;
  //set<int> adancimiNoduriNegre;
};

int N;
Nod noduri[1 + MAX_N];

int M;

Nod* queryLCA(Nod* u, Nod* v) {
  if (u->lant ==v->lant) {
    if (u->adancime < v->adancime) {
      return u;
    } else { // if (u->adancime >= v->adancime)
      return v;
    }
  } else {
    int hu = u->lant->tata->adancime;
    int hv = v->lant->tata->adancime;
    if (hu < hv) {
      return queryLCA(u, v->lant->tata);
    } else { // if (hu >= hv)
      return queryLCA(u->lant->tata, v);
    }
  }
}

int queryLCA(int idU, int idV) {
  //noduri[lanturi[noduri[u]->lant].tata].adancime;
  //(*(*(*noduri[u]).lant).tata).adancime;
  //noduri[u]->lant->tata->adancime;
  Nod* u = &noduri[idU];
  Nod* v = &noduri[idV];
  return queryLCA(u, v)->index;
}

void dfs(Nod* nod, int adancime = 1) {
  nod->adancime = adancime;
  nod->greutate = 1;
  Nod* fiu;
  int greutateFiu = 0;
  for (Nod* vecin : nod->vecini) {
    dfs(vecin, adancime + 1);
    nod->greutate += vecin->greutate;
    if (greutateFiu < vecin->greutate) {
      greutateFiu = vecin->greutate;
      fiu = vecin;
    }
  }
  //fiu->lant este calculat corect
  if (greutateFiu == 0) {
    //int a = new int; // NU
    //int *a = 7; // NU
    //int a = 7; // DA
    //int *a = new int; // DA
    //Lant l = Lant(); // DA
    //Lant *l = new Lant(); // DA
    nod->lant = new Lant();
  } else {
    nod->lant = fiu->lant;
    for (Nod* vecin : nod->vecini) {
      if (vecin != fiu) {
        vecin->lant->tata = nod;
      }
    }
  }
  nod->lant->noduri.push_back(nod);
}

int main() {
  freopen("lca.in", "r", stdin);
  freopen("lca.out", "w", stdout);
  scanf("%d%d", &N, &M);
  int radacina = 1;
  noduri[radacina].index = radacina;
  for (int i = 2; i <= N; i++) {
    int t;
    scanf("%d", &t);
    noduri[i].index = i;
    noduri[t].vecini.push_back(&noduri[i]);
  }
  dfs(&noduri[radacina]);
  noduri[0].adancime = 0;
  noduri[radacina].lant->tata = &noduri[0];
  for (int i = 1; i <= M; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    printf("%d\n", queryLCA(u, v));
  }
  return 0;
}