Cod sursa(job #2715817)

Utilizator FrostfireMagirescu Tudor Frostfire Data 4 martie 2021 11:41:35
Problema Matrice 2 Scor 45
Compilator cpp-64 Status done
Runda simularedelacasi1 Marime 2.59 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#define f first
#define s second
#define NMAX 300
#define inf 2000000000

using namespace std;

ifstream fin("matrice2.in");
ofstream fout("matrice2.out");

int n, q, nr, m, v[NMAX+10][NMAX+10], Tata[NMAX*NMAX+10], rang[NMAX*NMAX+10], nivel[NMAX*NMAX+10], tata[20][NMAX*NMAX+10], dp[20][NMAX*NMAX+10];
vector <pair <int, int> > nod[NMAX*NMAX+10];

struct date
{	int cost, n1, n2;
}K[4*NMAX*NMAX+10];

int cell(int r, int c)
{	return (r - 1) * n + c;
}

bool mycmp(date a, date b)
{	return a.cost > b.cost;
}

int findDaddy(int x)
{	int y = x, r = x;
	while(r != Tata[r]) r = Tata[r];
	while(x != Tata[x])
		{	y = Tata[x];
			Tata[x] = r;
			x = y;
		}
	return r;
}

void unite(int x, int y)
{	if(rang[x] < rang[y])
		Tata[x] = y;
	else
		Tata[y] = x;
	if(rang[x] == rang[y])
		rang[x]++;
}

void dfs(int x, int p)
{	tata[0][x] = p;
	nivel[x] = nivel[p] + 1;
	for(auto u : nod[x])
		if(u.s != p)
			{	dp[0][u.s] = u.f;
				dfs(u.s, x);
			}
}

int lca(int x, int y)
{	int mini = inf;
	if(nivel[x] < nivel[y]) swap(x, y);
	int dif = nivel[x] - nivel[y];
	for(int bit=0; (1<<bit)<=dif; bit++)
		if(dif & (1 << bit))
			{	mini = min(mini, dp[bit][x]);
				x = tata[bit][x];
			}
	if(x == y) return mini;
	for(int bit=19; bit; bit--)
		if(tata[bit][x] && tata[bit][x] != tata[bit][y])
			{	mini = min(mini, min(dp[bit][x], dp[bit][y]));
				x = tata[bit][x];
				y = tata[bit][y];
			}
	return min(mini, min(dp[0][x], dp[0][y]));
}

int main()
{
	fin >> n >> q;
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
			{	int nr1 = cell(i, j);
				fin >> v[i][j];
				if(i > 1)
					{	int nr2 = cell(i - 1, j);
						K[++nr] = {min(v[i][j], v[i-1][j]), nr1, nr2};
					}
				if(j > 1)
					{	int nr2 = cell(i, j - 1);
						K[++nr] = {min(v[i][j], v[i][j-1]), nr1, nr2};
					}
				Tata[nr1] = nr1;
				rang[nr1] = 1;
			}
	sort(K+1, K+nr+1, mycmp);
	for(int i=1; i<=nr; i++)
		{	int val1 = findDaddy(K[i].n1), val2 = findDaddy(K[i].n2);
			if(val1 == val2) continue;
			unite(val1, val2);
			nod[K[i].n1].push_back({K[i].cost, K[i].n2});
			nod[K[i].n2].push_back({K[i].cost, K[i].n1});
			m++;
		}
	m++;
	dfs(1, 0);
	for(int bit=1; (1<<bit)<m; bit++)
		for(int i=1; i<=m; i++)
			{	dp[bit][i] = min(dp[bit-1][i], dp[bit-1][tata[bit-1][i]]);
				tata[bit][i] = tata[bit-1][tata[bit-1][i]];
			}
	while(q--)
		{	int x1, y1, x2, y2;
			fin >> x1 >> y1 >> x2 >> y2;
			int nr1 = cell(x1, y1), nr2 = cell(x2, y2);
			fout << lca(nr1, nr2) << '\n';
		}
	return 0;
}