Cod sursa(job #1208305)

Utilizator dm1sevenDan Marius dm1seven Data 15 iulie 2014 13:07:57
Problema Lowest Common Ancestor Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 1.83 kb
#include <iostream>
using namespace std;
#include <fstream>

namespace e_040_lca_
{
	//depth of each node: inefficient
	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]; d++; }
			depths[i] = d;
		}
	}

	//depth by depth first search
	void dfs(int node, int depth, int N, int* parents, int* depths)
	{
		//assign the depth to the current node
		depths[node] = depth;
		//look for the childs of the current node
		for (int i = 2; i <= N; i++) if (parents[i] == node) dfs(i, depth + 1, N, parents, depths);
	}

	//simple lca routine: go up until we reach a common node
	int lca(int u, int v, int N, int* parents, int* depths)
	{
		
		//while (u != v) {
		//	if (depths[u] > depths[v]) u = parents[u];
		//	else v = parents[v];
		//}

		//return u; //return the common node

		int du = depths[u];
		int dv = depths[v];

		//dv has the highest depth
		if (du > dv) { swap(du, dv); swap(u, v); }
		for (int i = 1; i <= dv - du; i++) v = parents[v];
		//now we have two nodes u and v having the same depth du

		//go up until the common node
		while (u != v) { u = parents[u]; v = parents[v]; }

		return u; //return the common node
	}
}

//int e_040_lca()
int main()
{
	using namespace e_040_lca_;

	const int MAX_N = 100000;	
	int N, M;
	int parents[MAX_N + 1];
	parents[1] = 0; //the root has no parent
	int depths[MAX_N + 1];

	ifstream ifs("lca.in");
	ofstream ofs("lca.out");

	ifs >> N >> M;
	for (int i = 2; i <= N; i++) {
		int p;
		ifs >> p;
		parents[i] = p;
	}

	build_depth(N, parents, depths);
	//dfs(1, 0, N, parents, depths);

	for (int i = 1; i <= M; i++) {
		int u, v;
		ifs >> u >> v;
		ofs << lca(u, v, N, parents, depths) << "\n";
	}

	ifs.close();
	ofs.close();

	return 0;
}