Cod sursa(job #3186391)

Utilizator _andrei4567Stan Andrei _andrei4567 Data 22 decembrie 2023 21:11:41
Problema Matrice 2 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.83 kb
///trei posibilitati de optimizare
///divide cu dsu cu rollback
///cb in paralel (nu stiu sa implementez)
///small to large

///ar fi o idee sa le implementez si pe celelalte, ca ioit vine:(

#include <fstream>
#include <vector>
#include <algorithm>
#include <set>

using namespace std;

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

using pa = pair <int, int>;

const int N = 300;
const int M = 2e4;
int a[N + 1][N + 1];

int tata[N * N + 1];

bool viz[N * N + 1];

int rez[M + 1];

set <int> g[N * N + 1];

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

int n, q;

struct point
{
    int x, y;
    friend istream& operator >> (istream &is, point &a)
    {
        is >> a.x >> a.y;
        return is;
    }
};

struct ceva
{
    point x, y;
    int poz;
} qr[M + 1];

struct ap
{
    point x, y;
    int cost;
    bool operator < (const ap &a)const
    {
        return cost > a.cost;
    }
};

vector <ap> v;

int cheie (point a)
{
    return (a.x - 1) * n + a.y;
}

namespace DSU
{
int rad (int node)
{
    if (node == tata[node])return node;
    return tata[node] = rad (tata[node]);
}
void combine (int x, int y, int cost)
{
    int rx = rad (x);
    int ry = rad (y);
    if (rx != ry)
    {
        if (g[rx].size() >= g[ry].size())
            swap(rx, ry);
        tata[rx] = ry;
        for (auto it : g[rx])
        {
            if (g[ry].find(it) != g[ry].end())
            {
                rez[it] = cost;
                g[ry].erase (it);
            }
            else
                g[ry].insert (it);
        }
        g[rx].clear();
    }
}
}

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

void dfs (int x, int y)
{
    for (int i = 0; i < 2; ++i)
    {
        int xx = x + dx[i];
        int yy = y + dy[i];
        if (inside (xx, yy))
            v.push_back({{x, y}, {xx, yy}, min (a[x][y], a[xx][yy])});
    }
}

int main()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            cin >> a[i][j];
    for (int i = 1; i <= q; ++i)
    {
        cin >> qr[i].x >> qr[i].y;
        int cheiex = cheie (qr[i].x);
        int cheiey = cheie (qr[i].y);
        g[cheiex].insert(i);
        g[cheiey].insert(i);

    }
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            dfs (i, j);
    sort (v.begin(), v.end());
    for (int i = 1; i <= n * n; ++i)
        tata[i] = i;
    for (auto it : v)
    {
        point x = it.x;
        point y = it.y;
        int cheiex = cheie(x);
        int cheiey = cheie(y);
        DSU::combine (cheiex, cheiey, it.cost);
    }
    for (int i = 1; i <= q; ++i)
        cout << rez[i] << '\n';
    return 0;
}