Cod sursa(job #2680809)

Utilizator iancupoppPopp Iancu Alexandru iancupopp Data 4 decembrie 2020 14:02:48
Problema Matrice 2 Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.3 kb
#include <fstream>
#include <algorithm>
#include <set>
#include <vector>

using namespace std;

struct elem {
    int cost;
    int poz;
    bool operator<(const elem& e) {
        return cost < e.cost;
    }
};

struct query {
    int x[2];
    int y[2];
};

const int N = 90001, Q = 20000;

elem m[N];
query q[Q];
set<int> l[N];
vector<int> er;
int sef[N], rez[Q], c[N], n;

void unire(int a, int b) {
    for (auto i : l[a])
        if (l[b].find(i) != l[b].end()) {
            rez[i] = c[a];
            er.push_back(i);
        }
    for (auto i : er) {
        l[a].erase(i);
        l[b].erase(i);
    }
    while (!l[a].empty()) {
        l[b].insert(*l[a].begin());
        l[a].erase(l[a].begin());
    }
}

int sefsuprem(int x) {
    if (sef[x] == x)
        return x;
    return sef[x] = sefsuprem(sef[x]);
}

void adaug(elem e) {
    int poz, sef1, sef2;
    if (e.poz > n) {
        poz = e.poz - n;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
    if (e.poz % n) {
        poz = e.poz + 1;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
    if (e.poz <= n * (n - 1)) {
        poz = e.poz + n;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
    if (e.poz % n != 1) {
        poz = e.poz - 1;
        if (c[poz] >= e.cost) {
            sef1 = sefsuprem(e.poz);
            sef2 = sefsuprem(poz);
            if (sef1 != sef2) {
                c[sef1] = c[sef2] = e.cost;
                if (!l[sef1].empty())
                    unire(sef1, sef2);
                sef[sef1] = sef2;
            }
        }
    }
}

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

    int t, cmax = 0;
    in >> n >> t;
    for (int i = 1; i <= n * n; ++i) {
        in >> m[i].cost;
        c[i] = m[i].cost;
        cmax = max(cmax, c[i]);
        m[i].poz = i;
    }
    int poz;
    for (int i = 0; i < t; ++i) {
        in >> q[i].x[0] >> q[i].y[0] >> q[i].x[1] >> q[i].y[1];
        for (int j = 0; j < 2; ++j) {
            poz = n * (q[i].x[j] - 1) + q[i].y[j];
            l[poz].insert(i);
        }
    }

    sort(m + 1, m + n * n + 1);
    for (int i = 1; i <= n * n; ++i)
        sef[i] = i;

    int i = n * n;
    for (int cost = cmax; cost > 0 && i > 0; --cost)
        while (m[i].cost == cost) {
            adaug(m[i]);
            --i;
        }
    for (int i = 0; i < t; ++i)
        out << rez[i] << '\n';

    in.close();
    out.close();
    return 0;
}