Cod sursa(job #1937673)

Utilizator TimitocArdelean Andrei Timotei Timitoc Data 24 martie 2017 09:34:06
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.62 kb
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <vector>
#include <bitset>
#define MAXN 350
#define MAXQ 20050
#define MAXVAL 1000050
#define MAXNODES 200000

using namespace std;

int n, q, a[MAXN][MAXN];
struct query
{
    int x1, y1, x2, y2;
    query(int x1 = 0, int y1 = 0, int x2 = 0, int y2 = 0) : x1(x1), y1(y1), x2(x2), y2(y2) { }
};
struct elem
{
    int x, val;
    elem(int x = 0, int val = 0) : x(x), val(val) { }
    bool operator()(elem e, elem f)
    {
        return e.val > f.val;
    }
};
query stion[MAXQ];
int state[MAXQ];
int parent[MAXNODES];
struct muchie
{
    int x, y, cost;
    muchie(int x = 0, int y = 0, int cost = 0) : x(x), y(y), cost(cost) { }
    bool operator<(const muchie &e) const
    {
        return cost > e.cost;
    }
};
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

vector<muchie> muh;
vector<pair<int, int> > qries[MAXNODES];

void addMuhs(int x, int y)
{
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx >= 1 && nx <= n && ny >= 1 && ny <= n && (a[x][y] <= a[nx][ny]))
            muh.push_back(muchie(n*x+y, n*nx+ny, a[x][y]));
    }
}

void citire()
{
    scanf("%d %d", &n, &q);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            scanf("%d", &a[i][j]);
    for (int i = 1; i <= q; i++) {
        scanf("%d %d %d %d", &stion[i].x1, &stion[i].y1, &stion[i].x2, &stion[i].y2);
        qries[stion[i].x1*n + stion[i].y1].push_back(make_pair(stion[i].x2*n + stion[i].y2, i));
        qries[stion[i].x2*n + stion[i].y2].push_back(make_pair(stion[i].x1*n + stion[i].y1, i));
    }
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            addMuhs(i, j);
    sort(muh.begin(), muh.end());
}


int getParent(int x)
{
    if (parent[x] == x)
        return x;
    else
        return parent[x] = getParent(parent[x]);
}

int val[MAXNODES], repr[MAXNODES], nq;
vector<int> v[MAXNODES];

void build()
{
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++) {
            val[i*n+j] = a[i][j];
            parent[i*n+j] = i*n+j;
        }
    nq = n*n+n;
    for (muchie m : muh) {
        int p1 = getParent(m.x);
        int p2 = getParent(m.y);
        if (p1 != p2) {
            parent[p1] = ++nq;
            parent[p2] = nq;
            parent[nq] = nq;
            val[nq] = min(val[p1], val[p2]);
            v[nq].push_back(p1);
            v[nq].push_back(p2);
        }
    }
}

void debug(int nod)
{
    if (nod > n*n+n)
        printf("nou ");
    else
        printf("%d %d ", (nod-1)/5, (nod-1)%5+1);
    printf("%d\n", val[nod]);
    for (int y : v[nod])
        debug(y);
}

struct padure
{
    int mat[MAXNODES];
    void init()
    {
         for (int i = 1; i <= nq; i++)
            mat[i] = i;
    }

    int par(int x)
    {
        if (mat[x] == x)
            return x;
        return mat[x] = par(mat[x]);
    }
    int unify(int x, int y)
    {
        mat[par(x)] = par(y);
    }
    int united(int x, int y)
    {
        return par(x) == par(y);
    }
};
bitset<MAXNODES> viz;
padure p;

void solve(int nod)
{
    for (int y : v[nod]) {
        solve(y);
        p.unify(y, nod);
        repr[p.par(nod)] = nod;
    }
    viz[nod] = 1;
    for (pair<int, int> pa : qries[nod]) {
        if (viz[pa.first])
            state[pa.second] = val[repr[p.par(pa.first)]];
    }
}

void afisare()
{
    for (int i = 1; i <= q; i++)
        printf("%d\n", state[i]);
}

int main()
{
    freopen("matrice2.in", "r", stdin);
    freopen("matrice2.out", "w", stdout);

    citire();
    build();
    //debug(nq);
    p.init();
    solve(nq);
    afisare();

    return 0;
}