Cod sursa(job #1011439)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 16 octombrie 2013 20:49:51
Problema Matrice 2 Scor 45
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.38 kb

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

const int MAX_N(305);
const int MAX_Q(20005);

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];
std::pair<int,int> Query [MAX_Q];
std::pair<int,int> Sorted [MAX_Q];
int Result [MAX_Q];

inline void Read (void)
{
	std::freopen("matrice2.in","r",stdin);
	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]);
		}
	std::pair<int,int> a, b;
	for (i = 1 ; i <= q ; ++i)
	{
		std::scanf("%d %d %d %d",&a.first,&a.second,&b.first,&b.second);
		Query[i].first = Temp[a.first][a.second];
		Query[i].second = Temp[b.first][b.second];
		Sorted[i].first = std::min(Matrix[a.first][a.second],Matrix[b.first][b.second]);
		Sorted[i].second = i;
	}
	std::fclose(stdin);
}

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 void Compute (void)
{
	int i, j;
	for (i = End, j = 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);
		for (j = End ; j && Sorted[j].first >= v[i].first ; --j)
			if (!Result[Sorted[j].second] && Forest[Query[Sorted[j].second].first] && Forest[Query[Sorted[j].second].second] && ForestFind(Query[Sorted[j].second].first) == ForestFind(Query[Sorted[j].second].second))
				Result[Sorted[j].second] = v[i].first;
	}
}

inline void Print (void)
{
	std::freopen("matrice2.out","w",stdout);
	for (int i(1) ; i <= q ; ++i)
		std::printf("%d\n",Result[i]);
	std::fclose(stdout);
}

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);
	std::sort(Sorted + 1,Sorted + End + 1);
}

int main (void)
{
	Read();
	Build();
	Compute();
	Print();
	return 0;
}