Cod sursa(job #1932489)

Utilizator Firealex2Rotileanu Alexandru Firealex2 Data 19 martie 2017 20:22:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.77 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>

using namespace std;

ifstream fi("lca.in");
ofstream fo("lca.out");

int dp[17][100001], T[100001], L[100001], N, Q, x, y, result, hmax;
vector<int> muchii[100001];
void bfs(int start);
int lca(int node1, int node2);
void read();
void solve();

int main()
{
	read();
	solve();

	return 0;
}

void read()
{
	fi >> N >> Q;
	T[1] = -1;
	dp[0][1] = -1;
	for (int i = 2;i <= N;i++)
	{
		fi >> T[i];
		muchii[T[i]].push_back(i);
		dp[0][i] = T[i];
	}
}

void solve()
{
	bfs(1);

	for(int i=1;(1<<i)<=hmax;i++)
		for (int j = 1;j <= N;j++)
			dp[i][j] = dp[i - 1][dp[i - 1][j]];

	for (int i = 1;i <= Q;i++)
	{
		fi >> x >> y;
		result = lca(x, y);
		fo << result << '\n';
	}
}

void bfs(int start)
{
	queue<int> q;
	q.push(start);
	L[start] = 0;
	bool viz[100001];
	memset(viz, false, sizeof(viz));
	viz[start] = true;
	while (!q.empty())
	{
		int node = q.front();
		q.pop();
		for (int i = 0;i < muchii[node].size();i++)
		{
			int node2 = muchii[node][i];
			if (!viz[node2])
			{
				L[node2] = L[node] + 1;
				viz[node2] = true;
				q.push(node2);
				if (L[node2] > hmax)
					hmax = L[node2];
			}
			
		}
	}

	return;

}

int lca(int node1, int node2)
{
	int p;
	if (L[node1] < L[node2])
		p = node1, node1 = node2, node2 = p;
	int log;
	for (log = 1;(1 << log) <= L[node1];log++);
	log--;
	for (int i = log;i >= 0;i--)
		if (L[node1] - (1 << i) >= L[node2])
			node1 = dp[i][node1];
	if (node1 == node2)
		return node1;
	for (int i = log; i >= 0;i--)
		if (dp[i][node1]!=-1 && dp[i][node1] != dp[i][node2])
			node1 = dp[i][node1], node2 = dp[i][node2];
	return T[node1];
}