Cod sursa(job #1938382)

Utilizator mariakKapros Maria mariak Data 24 martie 2017 19:47:59
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.03 kb
#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define ll long long
#define pii pair <int, int>
#define maxN 311
#define maxQ 20011
using namespace std;

FILE *fin  = freopen("matrice2.in", "r", stdin);
FILE *fout = freopen("matrice2.out", "w", stdout);

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
/*-------Input data------*/
int N, Q, cnt;
struct Cell{
    int x, y, v;
    bool operator < (const Cell& who)const{
        return v > who.v;
    }
} c[maxN*maxN];
int id[maxN][maxN];

struct Query{
    pii from, to;
    int ans, id;
    bool operator < (const Query& who)const{
        return ans > who.ans;
    }
} q[maxQ];

bool used_cell[maxN][maxN];
bool used_node[maxN*maxN];
/*--------Graph data------*/
vector <int> G[maxN*maxN];
int dad[maxN*maxN];


int Find(int node){
    if(dad[node] == node)
        return node;
    dad[node] = Find(dad[node]);
    return dad[node];
}
void Union(int x, int y){
    x = Find(x); y = Find(y);
    if(x != y) dad[y]=x;
}

bool cmp(const Query& a, const Query& b){
    return a.id < b.id;
}

void init(){
    sort(q + 1, q + Q + 1);
    for(int i = 1; i <= cnt; ++ i)
        dad[i] = i;
    memset(used_node, 0, sizeof(used_node));
    memset(used_cell, 0, sizeof(used_cell));
}

int main(){
    /*------Input-------*/
    scanf("%d%d",&N, &Q);
    for(int i = 1; i <= N; ++ i){
        for(int j = 1; j <= N; ++ j){
            int value;
            scanf("%d", &value);
            id[i][j] = ++ cnt;
            c[cnt].x = i, c[cnt].y = j, c[cnt].v = value;
        }
    }
    for(int i = 1; i <= Q; ++ i){
        int x1, y1, x2, y2;
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        q[i].from = mp(x1, y1);
        q[i].to   = mp(x2, y2);
        q[i].ans = 0; q[i].id = i;
    }

    /*-----Build graph-----*/
    for(int i = 1; i <= N; ++ i){
        for(int j = 1; j <= N; ++ j){
           for(int k = 0; k < 4; ++ k){
                int xx = i + dx[k];
                int yy = j + dy[k];
                if(!id[xx][yy]) continue;
                G[id[i][j]].pb(id[xx][yy]);
           }
        }
    }

    /*----Binary search for solution-----*/
    sort(c + 1, c + cnt + 1);
    for(int p = (1 << 20);p; p >>= 1){
        init(); int j = 1;
        for(int i = 1; i <= Q; ++ i){

            while(j <= cnt && q[i].ans + p <= c[j].v) {
                Cell node = c[j ++];
                used_cell[node.x][node.y] = true;
                used_node[id[node.x][node.y]] = true;

                for(int nxt : G[id[node.x][node.y]]){
                    if(!used_node[nxt]) continue;
                    Union(id[node.x][node.y], nxt);
                }
            }
            int r1 = Find(id[q[i].from.first][q[i].from.second]);
            int r2 = Find(id[q[i].to.first][q[i].to.second]);
            if(r1 == r2) q[i].ans += p;
        }
    }

    sort(q + 1, q + Q + 1, cmp);
    for(int i = 1; i <= Q; ++ i)
        printf("%d\n", q[i].ans);

    return 0;
}