Cod sursa(job #1726354)

Utilizator lflorin29Florin Laiu lflorin29 Data 7 iulie 2016 20:11:06
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <bits/stdc++.h>

using namespace std;

struct intrebare{
    pair<int, int>from, to;
    int IND;
};

class multimi_disjuncte{
public:
   vector <int> root;
   int n;
   multimi_disjuncte(const int n = 0) : n(n) {
       root = vector<int>(n + 1);
       iota(begin(root), end(root), 0);
   }

   int tata(int x) {
    return x == root[x] ? x : root[x] = tata(root[x]);
   }

   void unite(int x, int y) {
       root[tata(x)] = tata(y);}
};

void uneste_vecini(int i, int j, int cost_minim, const vector<vector<int>>&valori, const vector<vector<int>>& coduri, multimi_disjuncte &padure) {
    static array<int, 4> dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};
    for(int k = 0; k < 4; ++k) {
       int ni = dx[k] + i, nj = dy[k] + j;
       if(ni < 0 || nj < 0 || ni >= valori.size() || nj >= valori.size()) continue;
       if(valori[ni][nj] < cost_minim) continue;
       padure.unite(coduri[i][j], coduri[ni][nj]);
    }
}

int main() {
    ifstream cin("matrice2.in");
    ofstream cout("matrice2.out");

    int n, cate_intreb;
    cin >> n >> cate_intreb;

    vector<vector<int>>a(n, vector<int>(n)), cod(n, vector<int>(n));
    for(int i = 0, id = 0; i < n; ++i)
       for(int j = 0; j < n; ++j)
          cin >> a[i][j], cod[i][j] = id++;

    vector<intrebare>qs(cate_intreb);
    for(int i = 0; i < cate_intreb; ++i) {
        pair<int, int>from, to;
        cin >> from.first >> from.second >> to.first >> to.second;
        from.first--, from.second--, to.first--, to.second--;
        qs[i] = intrebare{from, to, i};
    }

    vector < pair<int, int>> mat_sortata;
    for(int i = 0; i < n; ++i)
       for(int j = 0; j < n; ++j) mat_sortata.emplace_back(i, j);

    sort(begin(mat_sortata), end(mat_sortata), [&] (const pair<int, int>&lhs, const pair<int, int>&rhs) { return a[lhs.first][lhs.second] > a[rhs.first][rhs.second];});

    vector<int>cost_maxim(cate_intreb);

    for(int delta = 20; delta >= 0; delta--) {

       sort(begin(qs), end(qs), [&] (const intrebare &lhs, const intrebare &rhs) { return cost_maxim[lhs.IND] > cost_maxim[rhs.IND];});
       multimi_disjuncte padure(n * n);
       int poz = 0;

       for(auto intrebari : qs) {
          int cost_cerut = (1<<delta) + cost_maxim[intrebari.IND];
          while(poz < mat_sortata.size() && a[mat_sortata[poz].first][mat_sortata[poz].second] >= cost_cerut) {
              uneste_vecini(mat_sortata[poz].first, mat_sortata[poz].second, cost_cerut, a, cod, padure);
              ++poz;
          }

          int IDfrom = cod[intrebari.from.first][intrebari.from.second], IDto = cod[intrebari.to.first][intrebari.to.second];
          if(padure.tata(IDfrom) == padure.tata(IDto))
            cost_maxim[intrebari.IND] += 1<<delta;
       }
    }
    for(int i = 0; i < cate_intreb; ++i)
       cout << cost_maxim[i] << '\n';
    return 0;
}