Cod sursa(job #1081585)

Utilizator BuseSorinFMI Buse Sorin-Marian BuseSorin Data 13 ianuarie 2014 18:57:24
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Teme Pregatire ACM Unibuc 2013 Marime 2.09 kb
#include <fstream>
#include <algorithm>
#define MAXN 310
#define VMAX 1000000
#define MAXQ 20010
using namespace std;
const int dx[5] = { 0, 0, 1, -1 };
const int dy[5] = { 1, -1, 0, 0 };

typedef struct{
	int x, y, v;
}mat;
mat a[MAXN*MAXN];
int temp[MAXQ], poz[MAXN][MAXN], val[MAXN][MAXN], el1[MAXQ], el2[MAXQ], l, r, h, q, d, x1, x2, yf, y2, m, n, t[MAXN*MAXN], step, sol[MAXQ], p[MAXQ], viz[MAXN][MAXN];
int grupa(int i)
{
	if (t[i] == i) return i;
	t[i] = grupa(t[i]);
	return t[i];
}
void reunite(int i, int j)
{
	int up = grupa(i);
	t[up] = grupa(j);
}
bool cmp(mat x, mat y)
{
	return x.v>y.v;
}
bool cmp2(int x, int y)
{
	return temp[x]>temp[y];
}
bool valid(int x, int y)
{
	return (x <= m && x>0 && y <= m && y>0  && viz[x][y]);
}
int main()
{
	int i, j;
	ifstream fi("matrice2.in");
	ofstream fo("matrice2.out");
	fi >> n >> q;
	for (i = 1; i <= n; i++)
	for (j = 1; j <= n; j++)
	{
		fi >> a[(i - 1)*n + j].v;
		a[(i - 1)*n + j].x = i;
		a[(i - 1)*n + j].y = j;
	}
	m = n*n;
	sort(a + 1, a + m + 1, cmp);
	for (i = 1; i <= m; i++) { poz[a[i].x][a[i].y] = i; val[a[i].x][a[i].y] = a[i].v; }
	for (i = 1; i <= q; i++)
	{
		fi >> x1 >> yf >> x2 >> y2;
		el1[i] = poz[x1][yf]; el2[i] = poz[x2][y2];
	}
	int k;
	for (step = 1; step <= VMAX; step <<= 1);
	for (; step; step >>= 1)
	{
		for (i = 1; i <= m; i++) t[i] = i;
		for (i = 1; i <= q; i++) { temp[i] = sol[i] + step; p[i] = i; }
		sort(p + 1, p + q + 1, cmp2);
		for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) viz[i][j] = 0;
		for (i = 1, j = 1; i <= m && j <= q;)
		{
			for (; j <= q && temp[p[j]]>a[i].v; j++) if (grupa(el1[p[j]]) == grupa(el2[p[j]])) sol[p[j]] = temp[p[j]];
			for (k = i; a[i].v == a[k].v; i++)
			{
				viz[a[i].x][a[i].y] = 1;
				for (d = 0; d<4; d++)
				if (grupa(i) != grupa(poz[a[i].x + dx[d]][a[i].y + dy[d]]) && valid(a[i].x + dx[d], a[i].y + dy[d])) reunite(i, poz[a[i].x + dx[d]][a[i].y + dy[d]]);
			}
		}
		for (; j <= q; j++) if (grupa(el1[p[j]]) == grupa(el2[p[j]])) sol[p[j]] = temp[p[j]];
	}
	for (i = 1; i <= q; i++) fo << sol[i] << "\n";
	return 0;
}