Cod sursa(job #1428072)

Utilizator milijrCristian Militaru milijr Data 3 mai 2015 17:25:24
Problema Lowest Common Ancestor Scor 60
Compilator cpp Status done
Runda Arhiva educationala Marime 1.68 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

FILE *file_in;
FILE *file_out;

#define MAX_NO_NODES 100005

int n, m;
int parent[MAX_NO_NODES];
vector<int> ancestors[MAX_NO_NODES];

void getAncestors(int node)
{
	if (ancestors[node].size() == 0) {
		if (node != parent[node]) {
			getAncestors(parent[node]);
		}
		ancestors[node].insert(ancestors[node].begin(),
					ancestors[parent[node]].begin(),
					ancestors[parent[node]].end());
		ancestors[node].push_back(node);
	}
}

int findCommonAncestor(int node1, int node2)
{
	vector<int> ancestors1 = ancestors[node1];
	vector<int> ancestors2 = ancestors[node2];

        int size1 = ancestors1.size();
        int size2 = ancestors2.size();
        int minSize = (size1 < size2 ? size1 : size2);

        int left = 0;
        int right = minSize - 1;
        int mid;

        while (left <= right) {
		mid = (left + right) / 2;
		if (ancestors1[mid] == ancestors2[mid]) {
			if (mid == minSize - 1 || ancestors1[mid + 1] != ancestors2[mid + 1]) {
				return ancestors1[mid];
			} else {
				left = mid + 1;
			}
		} else {
			right = mid - 1;
		}
        }

        return -1;
}

int main()
{
	file_in = fopen("lca.in", "r");
	file_out = fopen("lca.out", "w");

	fscanf(file_in, "%d %d", &n, &m);
	parent[1] = 1;
	for (int i = 2; i <= n; i++) {
		fscanf(file_in, "%d", &parent[i]);
	}

	for (int i = 1; i <= n; i++) {
		getAncestors(i);
	}

	for (int i = 1; i <= m; i++) {
		int node1, node2;
		fscanf(file_in, "%d %d", &node1, &node2);
		fprintf(file_out, "%d\n", findCommonAncestor(node1, node2));
	}

	fclose(file_in);
	fclose(file_out);
	return 0;
}