Pagini recente » Cod sursa (job #2782719) | Cod sursa (job #950728) | Cod sursa (job #1402761) | Cod sursa (job #2390223) | Cod sursa (job #2627721)
#include <bits/stdc++.h>
#define maxn 305
#define maxdim 90005
std::ifstream fin ("matrice2.in");
std::ofstream fout ("matrice2.out");
int rank[maxdim];
int parent[maxdim];
void makeSet (int node){
rank[node] = 1;
parent[node] = node;
}
int findSet (int node){
if (parent[node] == node)
return node;
return parent[node] = findSet (parent[node]);
}
void unionSets (int node1, int node2){
node1 = findSet(node1);
node2 = findSet(node2);
if (node1 == node2)
return;
if (rank[node1] < rank[node2])
std::swap (node1, node2);
parent[node2] = node1;
if (rank[node1] == rank[node2])
rank[node1] ++;
}
struct Node{
int x, y;
int val, ind;
}v[maxdim];
bool nodeSort (Node a, Node b){
return a.val > b.val;
}
int ans[maxdim];
int mat[maxn][maxn];
struct Query{
int a, b;
}query[maxdim];
int left[maxdim], right[maxdim];
std::map <int, std::vector<int>> middle;
void binarySearch (int n, int Q, int size){
if (size == 0) return;
middle.clear();
int max = 0, i;
for (i=0; i<Q; i++)
middle[(left[i]+right[i])/2].push_back (i);
for (i=0; i<n*n; i++){
makeSet (i);
max = std::max (max, v[i].val);
}
i = 0;
for (int mid=max; mid>=0; mid--){
for (; i<n*n and v[i].val >= mid; i++){
int x = v[i].x;
int y = v[i].y;
int pos = v[i].ind;
if (x > 0 and mat[x-1][y] >= mid) unionSets (pos, pos-n);
if (y > 0 and mat[x][y-1] >= mid) unionSets (pos, pos-1);
if (x < n-1 and mat[x+1][y] >= mid) unionSets (pos, pos+n);
if (y < n-1 and mat[x][y+1] >= mid) unionSets (pos, pos+1);
}
for (auto i: middle[mid]){
if (findSet(query[i].a) == findSet(query[i].b))
left[i] = mid + 1;
else
right[i] = mid - 1;
}
middle[mid].clear();
}
binarySearch (n, Q, size/2);
}
int main()
{
int n, Q, i, j, x, y, max=0;
fin >> n >> Q;
for (i=0; i<n; i++){
for (j=0; j<n; j++){
v[i*n+j].x = i;
v[i*n+j].y = j;
v[i*n+j].ind = i*n+j;
fin >> v[i*n+j].val;
mat[i][j] = v[i*n+j].val;
max = std::max (max, mat[i][j]);
}
}
std::sort (v, v+n*n, nodeSort);
for (i=0; i<Q; i++){
fin >> x >> y; x--; y--;
query[i].a = x * n + y;
fin >> x >> y; x--; y--;
query[i].b = x * n + y;
left[i] = 0;
right[i] = max;
}
binarySearch(n, Q, max);
for (i=0; i<Q; i++)
fout << (left[i]+right[i])/2 << '\n';
return 0;
}