Pagini recente » Cod sursa (job #324288) | Cod sursa (job #1900834) | Cod sursa (job #1396837) | Cod sursa (job #239324) | Cod sursa (job #1588293)
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
ifstream fin("matrice2.in");
ofstream fout("matrice2.out");
const int dx[] = { 1, -1, 0, 0 };
const int dy[] = { 0, 0, 1, -1 };
struct Query {
int x1, y1, x2, y2;
int index;
Query() {}
Query(int x1, int y1, int x2, int y2, int index) {
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
this->index = index;
}
};
vector<Query> queries;
int a[305][305], b[305][305], sol[20005], disJoint[305 * 305];
vector< pair<int, int> > v;
inline bool comp1(const pair<int, int> &i, const pair<int, int> &j) {
return a[i.first][i.second] > a[j.first][j.second];
}
inline bool comp2(const Query &i, const Query &j) {
return sol[i.index] > sol[j.index];
}
inline int root(int node) {
int x = node;
while (disJoint[node] >= 0)
node = disJoint[node];
swap(x, node);
while (node != x) {
int tmp = disJoint[node];
disJoint[node] = x;
node = tmp;
}
return x;
}
inline void join(int node1, int node2) {
int root1 = root(node1);
int root2 = root(node2);
if (root1 == root2)
return;
if (disJoint[root1] <= disJoint[root2]) {
disJoint[root1] += disJoint[root2];
disJoint[root2] = root1;
}
else {
disJoint[root2] += disJoint[root1];
disJoint[root1] = root2;
}
}
int main() {
int n, q;
fin >> n >> q;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
fin >> a[i][j];
v.push_back(make_pair(i, j));
}
}
sort(v.begin(), v.end(), comp1);
for (int i = 1; i <= q; ++i) {
int x1, y1, x2, y2;
fin >> x1 >> y1 >> x2 >> y2;
queries.push_back(Query(x1, y1, x2, y2, i));
}
for (int step = (1 << 20); step; step >>= 1) {
sort(queries.begin(), queries.end(), comp2);
memset(b, 0, sizeof b);
for (unsigned int i = 0; i <= v.size(); ++i)
disJoint[i] = -1;
for (int i = 0, j = 0, curr = 0; j < (int)queries.size(); ++j) {
while (i < (int)v.size() && sol[queries[j].index] + step <= a[v[i].first][v[i].second]) {
int x = v[i].first;
int y = v[i].second;
b[x][y] = ++curr;
for (int d = 0; d < 4; ++d) {
int nextX = x + dx[d];
int nextY = y + dy[d];
if (b[nextX][nextY] == 0)
continue;
join(b[x][y], b[nextX][nextY]);
}
++i;
}
int aux = root(b[queries[j].x1][queries[j].y1]);
if (aux && aux == root(b[queries[j].x2][queries[j].y2]))
sol[queries[j].index] += step;
}
}
for (int i = 1; i <= q; ++i)
fout << sol[i] << '\n';
return 0;
}
//Trust me, I'm the Doctor!