Pagini recente » Cod sursa (job #3147610) | Cod sursa (job #3144270) | Cod sursa (job #3206132) | Cod sursa (job #59230) | Cod sursa (job #3207805)
#include <fstream>
#include <set>
#include <algorithm>
#include <vector>
using namespace std;
ifstream fin ("matrice2.in");
ofstream fout("matrice2.out");
struct elem
{
int val,x,y;
}V[90005];
struct elem1
{
int x1,x2,y1,y2,ind;
bool operator <(const elem1& b) const
{
return ind<b.ind;
}
};
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
set <elem1> M[90005];
vector <int> C[90005];
int n,val,m,x,y,x1,y1,x2,y2,k,a[305][305],T[90005],sol[20005],i,j,l;
bool inside(int x,int y){return x>=1&&x<=n&&y>=1&&y<=n;}
int get_root(int x)
{
int c=x;
while(T[x]>0)
x=T[x];
while(c!=x)
{
int aux=T[c];
T[c]=x;
c=aux;
}
return x;
}
void join(int x,int y)
{
int root_a=get_root(x);
int root_b=get_root(y);
if(root_a==root_b)
return;
if(T[root_a]>T[root_b])
swap(root_a,root_b);
T[root_a]+=T[root_b];
T[root_b]=root_a;
///dam join in aceeasi componenta, root_a o sa fie radacina principala
for(auto& j:M[root_b])///luam fiecare valoare din cealalta componenta
if(M[root_a].find(j)!=M[root_a].end())
{///daca valoarea din componenta 2 exista deja si in componenta 1
///inseamna ca 2 capete de query s-au intersectat
sol[j.ind]=val;///solutia pentru query-ul gasit este chiar
M[root_a].erase(j);///valoarea la care ajunsesem (fiind prima si cea
} ///mai mare valoare pentru care s-au intersectat)
else
M[root_a].insert(j);///in caz contrar adaugam la componenta
///elementul din cealalta componenta, asteptand pentru un eventual "match"
}
int main()
{
fin>>n>>m;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
fin>>x;
V[++k]={x,i,j};///adaugam toate valorile matricei intr-un vector
}
sort(V+1,V+k+1,[](elem a,elem b){return a.val<b.val;});
for(i=1;i<=k;i++)
{
a[V[i].x][V[i].y]=i;///atribuim fiecarui element indicele valorii
///din vectorul V dupa o sortare
T[i]=-1;
}
for(i=1;i<=m;i++)
{
fin>>x1>>y1>>x2>>y2;
elem1 val;
val={x1,y1,x2,y2,i};
///in M o sa retinem pentru fiecare "id" toti indicii matricei care
///sunt componente "ajunse" in id-ul respectiv
M[a[x1][y1]].insert(val);///de mentionat ca adaugam aceeasi valoare
M[a[x2][y2]].insert(val);///la cele 2 capete (o sa se intersecteze)
}
for(i=k;i>=1;i--)///o sa luam descrescator dupa valorile matricei
{
val=V[i].val;
for(auto& j:C[i])///in C[i] retinem toate valorile care au access la i
join(i,j);///asadar dam join in aceeasi componenta
for(l=0;l<4;l++)
{
x1=dx[l]+V[i].x;
y1=dy[l]+V[i].y;
if(inside(x1,y1)&&a[x1][y1]<=i)///a[x1][y1]<=i pentru a nu fi deja vizitat
C[a[x1][y1]].push_back(i);///adaugam la C-ul vecinilor lui i
}
}
for(i=1;i<=m;i++)
fout<<sol[i]<<"\n";
return 0;
}