Cod sursa(job #3186409)

Utilizator _andrei4567Stan Andrei _andrei4567 Data 22 decembrie 2023 23:05:36
Problema Matrice 2 Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.56 kb
///implementarea cu cb in paralel

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

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], low[N + 1], high[N + 1];

int tata[N * N + 1], h[N * N + 1];

bool viz[N * N + 1];

int rez[M + 1];

vector <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];

vector <ceva> toate;

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

vector <ap> v;

vector <int> check[N * N + 1];

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

namespace DSU
{
void init ()
{
    for (int i = 1; i <= n; ++i)
        tata[i] = i, h[i] = 1;
}
int rad (int node)
{
    if (node == tata[node])return node;
    return tata[node] = rad (tata[node]);
}
void combine (int x, int y)
{
    int rx = rad (x);
    int ry = rad (y);
    if (rx != ry)
    {
        if (h[rx] < h[ry])
        {
            tata[rx] = ry;
            h[ry] += h[rx];
        }
        else
        {
            tata[ry] = rx;
            h[rx] += h[ry];
        }
    }
}
}

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])});
    }
}

void solve ()
{
    for (int i = 1; i <= n; ++i)
    {
        low[i] = 1;
        high[i] = v.size() + 1;
    }
    bool done = true;
    while (done)
    {
        done = false;
        DSU::init();
        for (int i = 1; i <= n * n; ++i)
            viz[i] = 0;
        for (int i = 1; i <= q; ++i)
            if (low[i] != high[i])
                check[(low[i] + high[i]) >> 1].push_back(i);
        int poz = 1;
        for (auto it : v)
        {
            point x = it.x;
            point y = it.y;
            int cheiex = cheie(x);
            int cheiey = cheie(y);
            DSU::combine (cheiex, cheiey);
            viz[cheiex] = viz[cheiey] = 1;
            while (check[poz].size())
            {
                done = true;
                int nr = check[poz].back();
                check[poz].pop_back();
                if (viz[cheie(qr[nr].x)] && viz[cheie (qr[nr].y)])
                    high[nr] = poz, rez[nr] = it.cost;
                else
                    low[nr] = poz + 1;

            }
            ++poz;
        }
    }
}

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;
        toate.push_back({qr[i].x, qr[i].y, i});
        int cheiex = cheie (qr[i].x);
        int cheiey = cheie (qr[i].y);
        g[cheiex].push_back(i);
        g[cheiey].push_back(i);

    }
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= n; ++j)
            dfs (i, j);
    sort (v.begin(), v.end());
    solve ();
    for (int i = 1; i <= q; ++i)
        cout << rez[i] << '\n';
    return 0;
}