Cod sursa(job #1011408)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 16 octombrie 2013 20:19:07
Problema Matrice 2 Scor 35
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.87 kb

#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <cstring>

const int MAX_N(305);

int n, q, End;
std::vector<int> Graph [MAX_N * MAX_N];
int Matrix [MAX_N] [MAX_N];
int Temp [MAX_N] [MAX_N];
std::pair<int,int> v [MAX_N * MAX_N];
int Forest [MAX_N * MAX_N];

inline void Read (void)
{
	std::scanf("%d %d",&n,&q);
	int i, j, c(0);
	for (i = 1 ; i <= n ; ++i)
		for (j = 1 ; j <= n ; ++j)
		{
			std::scanf("%d",&Matrix[i][j]);
			Temp[i][j] = ++c;
			v[c] = std::make_pair(Matrix[i][j],Temp[i][j]);
		}
}

int ForestFind (int node)
{
	if (Forest[node] == node)
		return node;
	return Forest[node] = ForestFind(Forest[node]);
}

inline void ForestMerge (int a, int b)
{
	a = ForestFind(a);
	b = ForestFind(b);
	if (a < b)
		Forest[b] = a;
	else
		Forest[a] = b;
}

inline int Compute (int a, int b)
{
	std::memset(Forest + 1,0,sizeof(*Forest) * End);
	for (int i(End) ; i ; --i)
	{
		Forest[v[i].second] = v[i].second;
		for (auto it : Graph[v[i].second])
			if (Forest[it])
				ForestMerge(v[i].second,it);
		if (Forest[a] && Forest[b] && ForestFind(a) == ForestFind(b))
			return v[i].first;
	}
	return -1;
}

inline void Print (void)
{
	std::pair<int,int> a, b;
	while (q)
	{
		std::scanf("%d %d %d %d",&a.first,&a.second,&b.first,&b.second);
		std::printf("%d\n",Compute(Temp[a.first][a.second],Temp[b.first][b.second]));
		--q;
	}
}

inline void Build (void)
{
	const int WAY(4);
	const int X [ ] = {1,-1,0,0};
	const int Y [ ] = {0,0,-1,1};
	int i, j, k;
	for (i = 1 ; i <= n ; ++i)
		for (j = 1 ; j <= n ; ++j)
			for (k = 0 ; k < WAY ; ++k)
				if (Temp[i + X[k]][j + Y[k]])
					Graph[Temp[i][j]].push_back(Temp[i + X[k]][j + Y[k]]);
	End = n * n;
	std::sort(v + 1,v + End + 1);
}

int main (void)
{
	std::freopen("matrice2.in","r",stdin);
	std::freopen("matrice2.out","w",stdout);
	Read();
	Build();
	Print();
	std::fclose(stdin);
	std::fclose(stdout);
	return 0;
}