Cod sursa(job #3207810)

Utilizator Theo20067Cismaru Theodor-Alexe Theo20067 Data 27 februarie 2024 00:07:49
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.97 kb
#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];
const int dx[]={1,0,-1,0};
const int dy[]={0,1,0,-1};
set <int> 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]=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;
        ///in M o sa retinem pentru fiecare "id" o valoare unica pentru
        ///query-ul "i" deoarece e important atunci cand va avea loc
        ///intersectia a doua drumuri, daca drumul combinat contine ambele
        ///capete al unui query, am gasit solutie pt query-ul "i"
        M[a[x1][y1]].insert(i);
        M[a[x2][y2]].insert(i);
    }
    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;
}