Cod sursa(job #1798440)

Utilizator GabiTulbaGabi Tulba-Lecu GabiTulba Data 5 noiembrie 2016 11:05:20
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.84 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define MaxN 32001
#define MaxLog 16
#define INF 2140000000
using namespace std;
       
FILE *IN,*OUT;

int N,M,Max=0,MaxX,MaxY,Size=0,Root=0,X,Y,cost[MaxN],lvl[2*MaxN],t[MaxN],E[2*MaxN],rmq[MaxLog][2*MaxN],L[2*MaxN],first[MaxN];
vector <int> Graph[MaxN];
void Euler(int node,int level)
{
	E[++Size]=node;
	first[node]=Size;
	lvl[Size]=level;
	for(int i=0;i<Graph[node].size();i++)
	{
		Euler(Graph[node][i],level+1);
		E[++Size]=node;
		lvl[Size]=level;
	}
}
void Construct_RMQ()
{
	for(int i=1;i<=Size;i++)
		rmq[0][i]=i;
	for(int i=1;i<MaxLog;i++)
		for(int j=1;j<=Size;j++)
		{
			if(j>(1<<(i-1)))
			{
				rmq[i][j]=rmq[i-1][j];
				if(lvl[rmq[i][j]]>lvl[rmq[i-1][j-(1<<(i-1))]])
					rmq[i][j]=rmq[i-1][j-(1<<(i-1))];
			}
		}
}
void Construct_Log()
{
	for(int i=2;i<=Size;i++)
		L[i]=L[i/2]+1;
}
int LCA(int X,int Y)
{
	X=first[X];
	Y=first[Y];
	if(X>Y)
	{
		int t=X;
		X=Y;
		Y=t;
	}
	int Log=L[Y-X+1];
	int Min=rmq[Log][Y];
	if(lvl[Min]>lvl[rmq[Log][Y-(1<<Log)+1]])
		Min=rmq[Log][Y-(1<<Log)+1];

	return E[Min];
}
int main()
{
    IN=fopen("concurs.in","r");
    OUT=fopen("concurs.out","w");
    
	fscanf(IN,"%d%d",&N,&M);
	for(int i=1;i<=N;i++)
		fscanf(IN,"%d",&cost[i]);
	for(int i=1;i<N;i++)
	{
		fscanf(IN,"%d%d",&X,&Y);
		t[Y]=X;
		Graph[X].push_back(Y);
	}
	for(int i=1;i<=N;i++)
		if(t[i]==0)
		{
			Root=i;
			break;
		}
	lvl[0]=INF;
	Euler(Root,0);
	Construct_Log();
	Construct_RMQ();
	for(int i=1;i<=M;i++)
	{
		int aux;
		fscanf(IN,"%d%d",&X,&Y);
		aux=LCA(X,Y);
		if(Max<cost[aux])
			Max=cost[aux],MaxY=Y,MaxX=X;
		else if(Max==cost[aux])
		{
			if(X<MaxX)
				MaxX=X,MaxY=Y;
			else if(X==MaxX&&Y<MaxY)
				Y=MaxY;
		}
	}
	fprintf(OUT,"%d %d %d",Max,MaxX,MaxY);
    return 0;
}