Pagini recente » Cod sursa (job #1197044) | Cod sursa (job #1211541) | Cod sursa (job #2839344) | Cod sursa (job #2362393) | Cod sursa (job #1208536)
#include <iostream>
using namespace std;
#include <fstream>
#include <algorithm>
namespace e_040_lca_
{
//depth of each node
void build_depth(int N, int** parents, int* depths)
{
for (int i = 1; i <= N; i++) {
int d = 0; int p = i;
while (p != 1) { p = parents[p][1]; d++; }
depths[i] = d;
}
}
void build_2powk_parents(int N, int** parents)
{
int log_N = (int) ceil(log(N));
for (int k = 1; k < log_N; k++)
{
for (int i = 2; i <= N; i++) {
int pk = parents[i][k];
parents[i][k + 1] = parents[pk][k];
}
}
}
int lca(int u, int v, int N, int** parents)
{
if (u == 1 || v == 1) return 1;
if (u == v) return u;
bool found = false;
int log_N = (int) ceil(log(N));
int ku, kv;
for (ku = 0; ku <= log_N; ku++) {
for (kv = 0; kv <= log_N; kv++) {
if (parents[u][ku] == parents[v][kv]) found = true;
if (found) break;
}
if (found) break;
}
if (ku == 0 || ku == 1) return parents[u][ku];
if (kv == 0 || kv == 1) return parents[v][kv];
int kum1 = ku - 1, kvm1 = kv - 1;
int u1 = parents[u][kum1];
int v1 = parents[v][kvm1];
return lca(u1, v1, N, parents);
}
}
//int e_040_lca()
int main()
{
using namespace e_040_lca_;
int N, M;
ifstream ifs("lca.in");
ofstream ofs("lca.out");
ifs >> N >> M;
int log_N = (int) ceil(log(N));
int** parents = new int*[N + 1];
for (int i = 0; i <= N; i++) parents[i] = new int[log_N + 1];
int* depths = new int[N + 1];
//initializations
for (int k = 0; k <= log_N; k++) {
parents[1][k] = 0; //the root has no parent
parents[0][k] = 0; //used when building 2^k parents
}
parents[1][0] = 1;
for (int i = 2; i <= N; i++) {
int p;
ifs >> p;
parents[i][0] = i;
parents[i][1] = p;
}
build_depth(N, parents, depths);
//dfs(1, 0, N, parents, depths);
build_2powk_parents(N, parents);
for (int i = 1; i <= M; i++) {
int u, v;
ifs >> u >> v;
ofs << lca(u, v, N, parents) << "\n";
}
ifs.close();
ofs.close();
return 0;
}