Cod sursa(job #1208536)

Utilizator dm1sevenDan Marius dm1seven Data 15 iulie 2014 23:53:17
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#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;
}