Cod sursa(job #1290943)

Utilizator vladrochianVlad Rochian vladrochian Data 11 decembrie 2014 23:05:03
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.76 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;

const int kMaxN = 305, kMaxN2 = 100000, dir[] = {-kMaxN, -1, 1, kMaxN}, kInf = 0x3f3f3f3f;

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

int N, Q, val[kMaxN2], father[kMaxN2], level[kMaxN2], join_val[kMaxN2];
vector<int> G[kMaxN2];
struct Compare {
	bool operator()(int a, int b) {
		return val[a] < val[b];
	}
};
priority_queue<int, vector<int>, Compare> pq;

inline int Index(int x, int y) {
	return x * kMaxN + y;
}

int Root(int x) {
	while (father[x])
		x = father[x];
	return x;
}

int Link(int x, int y, int val) {
	if (level[x] < level[y]) {
		father[x] = y;
		join_val[x] = val;
		G[y].push_back(x);
		return y;
	}
	if (level[x] == level[y])
		++level[x];
	father[y] = x;
	join_val[y] = val;
	G[x].push_back(y);
	return x;
}

void DFS(int node) {
	for (int i : G[node]) {
		level[i] = level[node] + 1;
		DFS(i);
	}
}

int Query(int x, int y) {
	int ans = kInf;
	while (x != y)
		if (level[x] > level[y]) {
			ans = min(ans, join_val[x]);
			x = father[x];
		} else {
			ans = min(ans, join_val[y]);
			y = father[y];
		}
	return ans;
}

int main() {
	fin >> N >> Q;
	for (int i = 1; i <= N; ++i)
		for (int j = 1; j <= N; ++j) {
			fin >> val[Index(i, j)];
			pq.push(Index(i, j));
		}
	while (!pq.empty()) {
		int crt = pq.top(), root = crt;
		pq.pop();
		level[crt] = 1;
		for (int i = 0; i < 4; ++i) {
			int nb = Root(crt + dir[i]);
			if (level[nb] && nb != root)
				root = Link(root, nb, val[crt]);
		}
	}
	int root = Root(Index(1, 1));
	level[root] = 0;
	DFS(root);
	while (Q--) {
		int x1, y1, x2, y2;
		fin >> x1 >> y1 >> x2 >> y2;
		fout << Query(Index(x1, y1), Index(x2, y2)) << "\n";
	}
	return 0;
}