Cod sursa(job #2982984)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 21 februarie 2023 12:37:38
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include<fstream>
#include<queue>
#include<vector>
#include<algorithm>
#include<bitset>
using namespace std;


ifstream fin("matrice2.in");
ofstream fout("matrice2.out");

int v[301][301],nr[301][301],q,n,m;

const int dx[] = {-1,0,1,0};
const int dy[] = {0,-1,0,1};

bool inmat(int a,int b)
{
    return (a >= 1 && b >= 1 && n >= a && n >= b);
}

struct query
{
    int ls,cs,lf,cf,rez,ind;
};

struct muchie
{
    int to,from,cost;
};

bool cmp(const muchie &a,const muchie &b)
{
    return a.cost > b.cost;
}

vector<query> queries;


int ans[20002],curr[20002];

vector<int> t;

int root(int nod)
{
    return t[nod] ? t[nod] = root(t[nod]) : nod;
}

void unite(int a,int b)
{
    int ra = root(a),rb = root(b);
    if(ra != rb) t[ra] = rb;
}

vector<muchie> muchii;

bool funct(const query &a,const query &b)
{
    return a.rez > b.rez;
}

int main()
{
    int a,b,c,d,e = 0;
    fin >> n >> q;
    for(int i = 1; i <= n ; i++)
        for(int j = 1; j <= n ; j++)
            fin >> v[i][j];

    for(int i = 1; i <= n ; i++)
        for(int j = 1; j <= n ; j++)
            nr[i][j] = e++;

    int vmax = 0;

    t.resize(e);
    for(int i = 1; i <= n ; i++)
        {
            for(int j = 1; j <= n ; j++)
                {
                    vmax = max(vmax,v[i][j]);
                    for(int k = 0; k < 4 ; k++)
                        {
                            int vi = i + dx[k];
                            int vj = j + dy[k];
                            if(!inmat(vi,vj)) continue;
                            muchii.push_back({nr[i][j],nr[vi][vj],min(v[i][j],v[vi][vj])});
                        }
                }
        }

    for(int i = 0; i < q ; i++)
        {
            fin >> a >> b >> c >> d;
            queries.push_back({a,b,c,d,0,i});
        }

    sort(muchii.begin(),muchii.end(),cmp);


    int pas = 1; while(pas < vmax) pas <<= 1;
    for(; pas ; pas >>= 1)
        {
            fill(t.begin(),t.end(),0);
            sort(queries.begin(),queries.end(),funct);
            for(int i = 0 , j = 0; i < q ; i++)
                {
                    if(queries[i].rez + pas > vmax) continue; /// daca putem adauga o muchie pt query i,o putem adauga si pentru queryul i + k,deoarece i.rez >= i + k .rez
                    while(j < muchii.size() && muchii[j].cost >= queries[i].rez + pas)
                        {
                            unite(muchii[j].to,muchii[j].from);
                            j++;
                        }

                    int u = root(nr[queries[i].ls][queries[i].cs]);
                    int v = root(nr[queries[i].lf][queries[i].cf]);
                    if(u == v) queries[i].rez += pas;
                }
        }

    for(auto it : queries) ans[it.ind] = it.rez;
    for(int i = 0 ; i < q ; i++) fout << ans[i] << '\n';

}