Cod sursa(job #1362235)

Utilizator assa98Andrei Stanciu assa98 Data 26 februarie 2015 11:11:46
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;

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

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

struct elem {
    int x, y, val;
    elem(int _x = 0, int _y = 0, int _val = 0) {
        x = _x;
        y = _y;
        val = _val;
    }

    inline bool operator < (const elem &o) const {
        return val > o.val;
    }
};

struct elem2 {
    int x, y, val, poz;
    elem2(int _x = 0, int _y = 0, int _val = 0, int _poz = 0) {
        x = _x;
        y = _y;
        val = _val;
        poz = _poz;
    }

    inline bool operator < (const elem2 &o) const {
        return val > o.val;
    }
};

class cmp {
public:
    inline bool operator () (const elem2 &a, const elem2 &b) const {
        return a.poz < b.poz;
    }
};


int a[MAX_N][MAX_N];
vector<elem> v;
vector<elem2> q;

int dad[MAX_N * MAX_N];
int h[MAX_N * MAX_N];

void initializare(int n) {
    for(int i = 0; i < n; i++) {
        dad[i] = -1;
        h[i] = 1;
    }
}

int find(int nod) {
    if(dad[nod] == nod) {
        return nod;
    }
    return dad[nod] = find(dad[nod]);
}

void merge(int a, int b) {
    a = find(a);
    b = find(b);
    if(a == b) {
        return;
    }

    if(h[a] < h[b]) {
        dad[a] = b;
    }
    else if(h[b] < h[a]) {
        dad[b] = a;
    }
    else {
        h[a]++;
        dad[b] = a;
    }
}

inline bool inborder(int x, int y, int n) {
    return x >= 1 && x <= n && y >= 1 && y <= n;
}

int main() {
    int n, m;
    fin >> n >> m;

    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            int a;
            fin >> a;
            v.push_back(elem(i, j, a));
        }
    }
    sort(v.begin(), v.end());

    for(int i = 0; i < (int)v.size(); i++) {
        a[v[i].x][v[i].y] = i;
    }

    for(int i = 1; i <= m; i++) {
        int x1, x2, y1, y2;
        fin >> x1 >> y1 >> x2 >> y2;
        q.push_back(elem2(a[x1][y1], a[x2][y2], 0, i));
    }

    for(int b = 19; b >= 0; b--) {
        sort(q.begin(), q.end());
        initializare(n * n);
        auto itq = q.begin();
        for(auto it : v) {
            while(itq != q.end() && itq->val + (1 << b) > it.val) {
                if(dad[itq->x] != -1 && find(itq->x) == find(itq->y)) {
                    itq->val += (1 << b);
                }
                itq++;
            }

            dad[a[it.x][it.y]] = a[it.x][it.y];
            for(int i = 0; i < 4; i++) {
                if(inborder(it.x + dx[i], it.y + dy[i], n) && dad[a[it.x + dx[i]][it.y + dy[i]]] != -1) {
                    merge(a[it.x][it.y], a[it.x + dx[i]][it.y + dy[i]]);
                }
            }
        }
        while(itq != q.end()) {
            if(dad[itq->x] != -1 && find(itq->x) == find(itq->y)) {
                itq->val += (1 << b);
            }
            itq++;
        }
    }

    sort(q.begin(), q.end(), cmp());
    for(auto it : q) {
        fout << it.val << '\n';
    }

    return 0;
}