Cod sursa(job #1966470)

Utilizator lflorin29Florin Laiu lflorin29 Data 15 aprilie 2017 12:02:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.21 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 1e5 + 2;

int n, m, chain[MAX_N], sz[MAX_N], chainFather[MAX_N], father[MAX_N], depth[MAX_N];
vector<int>g[MAX_N];

void ReadTree ()
{
	scanf("%d%d", &n, &m);

	for (int i = 2; i <= n; ++i)
	{
		scanf("%d", &father[i]);
		g[father[i]].push_back(i);
	}
}

void Dfs (int nod)
{
	depth[nod] = depth[father[nod]] + 1;
	sz[nod] = 1;
	int best_son = 0;

	for (auto i : g[nod])
	{
		Dfs(i);
		sz[nod] += sz[i];

		if (!best_son || sz[i] > sz[best_son])
			best_son = i;
	}

	if (!best_son)
	{
		chain[nod] = nod;
	}
	else
	{
		chain[nod] = chain[best_son];
	}

	chainFather[chain[nod]] = father[nod];
}

inline int Lca(int a, int b)
{
	int c1 = chain[a], c2 = chain[b];

	if (c1 == c2)
	{
		return depth[a] < depth[b] ? a : b;
	}

	if(depth[chainFather[c1]] > depth[chainFather[c2]])
	    return Lca(chainFather[c1], b);
    return Lca(a, chainFather[c2]);
}
void Solve()
{
	for (int i = 1; i <= m; ++i)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		printf("%d\n", Lca(a, b));
	}
}
int main()
{
	freopen("lca.in", "r", stdin);
	freopen("lca.out", "w", stdout);

	ReadTree (), Dfs (1);
	Solve ();
	return 0;
}