Cod sursa(job #1673398)

Utilizator emanuel_rRamneantu Emanuel emanuel_r Data 3 aprilie 2016 19:16:10
Problema Matrice 2 Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<cmath>
#include<stack>
#include<bitset>
#include<algorithm>

using namespace std;

ifstream f("matrice2.in");
ofstream g("matrice2.out");

struct question{
    int x1, y1, x2, y2, ind, ans;
};

int A[305][305], TT[100000];
pair <int, int> V[100000];
int n, q;
vector <question> Q;
int x[] = {1, 0, -1, 0}, y[] = {0, 1, 0, -1};

void Read()
{
    int i, j;
    question qa;

    f>>n>>q;
    for(i=1; i<=n; i++)
        for(j=1; j<=n; j++){
            f>>A[i][j];
            V[(i-1)*n + j].first = i;
            V[(i-1)*n + j].second = j;
        }

    qa.ans = 0;
    for(i=1; i<=q; i++){
        qa.ind = i;
        f>>qa.x1>>qa.y1>>qa.x2>>qa.y2;
        Q.push_back(qa);
    }
}

bool compareM(pair <int, int> x, pair <int, int> y)
{
    return A[x.first][x.second] > A[y.first][y.second];
}

bool compareA(question x, question y)
{
    return x.ans > y.ans;
}

bool compareI(question x, question y)
{
    return x.ind < y.ind;
}

int Father(int i, int j)
{
    int nod = (i-1)*n + j;
    while(TT[nod] != nod && TT[nod] != 0){
        nod = TT[nod];
    }

    return nod;
}

void Unite(int i, int j)
{
    int k, ivec, jvec, nod, vecin;
    for(k=0; k<4; k++){
        ivec = i + x[k];
        jvec = j + y[k];
        nod = (i-1) * n + j;
        vecin = (ivec-1) * n + jvec;
        if(ivec > n || ivec == 0 || jvec > n || jvec == 0 || TT[vecin] == 0)
            continue;

        TT[Father(ivec, jvec)] = nod;
    }
    TT[nod] = nod;
}

void Solve()
{
    int i, j, step;

    sort(V + 1, V + n*n + 1, compareM);

    for(step = 30; step >= 0; step--){
        sort(Q.begin(), Q.end(), compareA);
        for(i=1; i<=n*n; i++)
                TT[i] = 0;
        j=1;
        for(i=0; i<q; i++){
            for( ; Q[i].ans + (1<<step) <= A[V[j].first][V[j].second] && j <= n*n; j++)
                Unite(V[j].first, V[j].second);
            if(Father(Q[i].x1, Q[i].y1) == Father(Q[i].x2, Q[i].y2))
                Q[i].ans += (1<<step);
        }
    }
}

void Print()
{
    sort(Q.begin(), Q.end(), compareI);
    for(int i=0; i<q; i++)
        g<<Q[i].ans<<"\n";
}

int main()
{
    Read();
    Solve();
    Print();
    return 0;
}