Pagini recente » Cod sursa (job #1575484) | Cod sursa (job #2226433) | Cod sursa (job #2089366) | Cod sursa (job #851517) | Cod sursa (job #1734780)
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream cin("matrice2.in");
ofstream cout("matrice2.out");
const int MaxN = 905;
const int dir[4][2] = {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
int father[MaxN], depth[MaxN], mat[MaxN][MaxN];
int n, q, N;
class m_p {
public:
int pos1, pos2, ans, ind;
m_p(int _pos1 = 0, int _pos2 = 0, int _ans = 0, int _ind = 0) {
pos1 = _pos1;
pos2 = _pos2;
ans = _ans;
ind = _ind;
}
inline bool operator < (const m_p &other) const {
return ans > other.ans;
}
};
vector <m_p> Qry;
class m_v {
public:
int val, x, y;
m_v(int _val = 0, int _x = 0, int _y = 0) {
val = _val;
x = _x;
y = _y;
}
inline bool operator < (const m_v &other) const {
return val > other.val;
}
};
vector <m_v> v;
void DSUInit() {
for (int i = 1; i <= N; ++i) {
father[i] = -1;
depth[i] = 1;
}
}
int FindRt(int node) {
if (father[node] == node) {
return node;
}
return father[node] = FindRt(father[node]);
}
void DSUMerge(int node1, int node2) {
int Rt1 = FindRt(node1);
int Rt2 = FindRt(node2);
if (depth[Rt1] < depth[Rt2]) {
father[Rt1] = Rt2;
}
else if (depth[Rt2] < depth[Rt1]) {
father[Rt2] = Rt1;
}
else {
father[Rt2] = Rt1;
++depth[Rt1];
}
}
inline bool cmp(const m_p &a, const m_p &b) {
return a.ind < b.ind;
}
inline bool InBound(const int &x, const int &y) {
return x >= 1 and x <= n and y >= 1 and y <= n;
}
int main() {
cin >> n >> q;
N = n * n;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
int x;
cin >> x;
v.push_back(m_v(x, i, j));
}
}
for (int i = 1; i <= (int) v.size(); ++i) {
mat[v[i - 1].x][v[i - 1].y] = i;
}
for (int i = 1; i <= q; ++i) {
int a, b;
cin >> a >> b;
int pos1 = mat[a][b];
cin >> a >> b;
int pos2 = mat[a][b];
Qry.push_back(m_p(pos1, pos2, 0, i));
}
sort(v.begin(), v.end());
for (int pow = 20; pow >= 0; --pow) {
DSUInit();
sort(Qry.begin(), Qry.end());
auto itQ = Qry.begin();
for (auto itV: v) {
while (itQ < Qry.end() and itQ->ans + (1 << pow) > itV.val) {
if (father[itQ->pos1] != -1 and father[itQ->pos2] != -1 and FindRt(itQ->pos1) == FindRt(itQ->pos2)) {
itQ->ans += (1 << pow);
}
++itQ;
}
father[mat[itV.x][itV.y]] = mat[itV.x][itV.y];
for (int iDir = 0; iDir < 4; ++iDir) {
int NewX = itV.x + dir[iDir][0];
int NewY = itV.y + dir[iDir][1];
if (InBound(NewX, NewY) and father[mat[NewX][NewY]] != -1) {
DSUMerge(mat[itV.x][itV.y], mat[NewX][NewY]);
}
}
}
while (itQ < Qry.end()) {
if (father[itQ->pos1] != -1 and father[itQ->pos2] != -1 and FindRt(itQ->pos1) == FindRt(itQ->pos2)) {
itQ->ans += (1 << pow);
}
++itQ;
}
}
sort(Qry.begin(), Qry.end(), cmp);
for (auto itQ: Qry) {
cout << itQ.ans << '\n';
}
return 0;
}