Cod sursa(job #525821)

Utilizator loginLogin Iustin Anca login Data 26 ianuarie 2011 14:27:56
Problema Matrice 2 Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.35 kb
# include <fstream>
# include <iomanip>
# include <iostream>
# include <vector>
# include <set>
# include <algorithm>
# define MaxN 303
# define DIM 100000
# define MIN -1000001
# define max(a,b) (a>b?a:b)
# define pb push_back
# define mp make_pair
using namespace std;

int n, q, a[MaxN][MaxN], t[22][DIM], c[22][DIM], v[DIM], l[DIM];
int di[2]={0, 1}, dj[2]={1, 0};
vector< pair<int,int> >G[DIM];
set< pair<int,int> >S;

ifstream fin ("matrice2.in");

void read ()
{
	fin>>n>>q;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			fin>>a[i][j];			
}

int inline in_m (int i, int j)
{
	return (i && j && i<=n*n && j<=n*n);
}

void fa_graf ()
{
	int x, y, c;
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			for(int k=0;k<2;++k)
				if (in_m(i+di[k],j+dj[k]))
				{
					x=(i-1)*n+j;
					y=(i+di[k]-1)*n+j+dj[k];
					c=max(-a[i][j],-a[i+di[k]][j+dj[k]]);
					G[x].pb(mp(y,c));
					G[y].pb(mp(x,c));
				}
}

void apm ()
{
	S.insert(mp(MIN,1));
	c[0][1]=MIN;
	int k;
	while (S.size())
	{
		k=(*S.begin()).second;
		S.erase(S.begin());
		if (!v[k])
		{
			v[k]=1;
			for(int i=0;i<G[k].size();++i)
				if (!v[G[k][i].first] && c[0][G[k][i].first]>G[k][i].second)
				{
					c[0][G[k][i].first]=G[k][i].second;
					t[0][G[k][i].first]=k;
					l[G[k][i].first]=l[k]+1;
					S.insert(mp(G[k][i].second,G[k][i].first));
				}
		}
	}
}

void tati ()
{
	int cont = 1;
	for (int i=1;cont;++i)
	{
		cont = 0;
		for(int j=2;j<=n*n;++j)
			if (t[i-1][t[i-1][j]])
			{
				cont = 1;
				t[i][j]=t[i-1][t[i-1][j]];
				c[i][j]=max(c[i-1][j],c[i-1][t[i-1][j]]);
			}
	}	
}

int query (int x, int y)
{
	int a, b, rez=MIN, stp=17;
	if (l[x]<l[y])a=x,b=y;
	else a=y,b=x;
	while (l[a]!=l[b])
	{
		if (l[t[0][b]]==l[a])
			b=t[0][b];
		else
		{
			while (!t[stp][b] || l[t[stp][b]]<=l[a])
				stp/=2;
			rez=max(rez,c[stp][b]);
			b=t[stp][b];
		}
	}
	if (a!=b)
	{
		stp=17;
		while (a!=b)
		{
			if (t[0][a]==t[0][b])
			{
				rez=max(rez,max(c[0][a],c[0][b]));
				a=t[0][a];
				b=t[0][b];
			}
			else
			{
				while (!t[stp][a] || t[stp][a]==t[stp][b])
					stp/=2;
				rez=max(rez,max(c[stp][a],c[stp][b]));
				a=t[stp][a];
				b=t[stp][b];
			}
		}
	}
	return -rez;
}
							
int main()
{
	read ();
	fa_graf();
	apm();
	tati();
	int x1, x2, y1, y2, A, B;
	freopen("matrice2.out", "w", stdout);
	for(;q--;)
	{
		fin>>x1>>y1>>x2>>y2;
		A=(x1-1)*n+y1;
		B=(x2-1)*n+y2;
		printf("%d\n", query(A, B));
	}
	return 0;
}