Cod sursa(job #1392923)

Utilizator retrogradLucian Bicsi retrograd Data 18 martie 2015 23:22:50
Problema Matrice 2 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.76 kb
#include<fstream>
#include<vector>
#include<algorithm>

using namespace std;
typedef int var;

ifstream fin("matrice.in");
ofstream fout("matrice.out");

struct Edge {
    var a, b, c;
    Edge(var x, var y, var z) {
        a = x;
        b = y;
        c = z;
    }
    const bool operator<(const Edge &e) const{
        return c > e.c;
    }
};

#define MAXN 305
#define MAX_NO 305*305*4

var n, m;
var A[MAXN][MAXN];
vector<var> G[MAX_NO];
vector<Edge> E;

var COST[MAX_NO], PARENT[MAX_NO];


var Parent[MAXN*MAXN], Rank[MAXN*MAXN], Node[MAXN*MAXN];
var Find(var f) {
    if(!Parent[f]) return f;
    Parent[f] = Find(Parent[f]);
    return Parent[f];
}
void Union(var r1, var r2, var under) {
    r1 = Find(r1);
    r2 = Find(r2);
    if(Rank[r1] < Rank[r2]) {
        Parent[r1] = r2;
        Node[r2] = under;
    } else {
        Parent[r2] = r1;
        Node[r1] = under;
        Rank[r1] += (Rank[r1] == Rank[r2]);
    }
}

var toNod(var i, var j) {
    return n*(i-1)+j;
}


void afisEdge(Edge e) {
    var i1 = (e.a - 1) / n + 1;
    var j1 = (e.a - 1) % n + 1;

    var i2 = (e.b - 1) / n + 1;
    var j2 = (e.b - 1) % n + 1;

    fout<<i1<<" "<<j1<<" | "<<i2<<" "<<j2<<" : "<<e.c<<'\n';
}


struct Rmq {
    var rmq, sol;
    Rmq(var a, var b) {
        sol = a;
        rmq = b;
    }
    Rmq() {}
    const bool operator <(const Rmq &r) const {
        return rmq < r.rmq;
    }
};

var tm;
var B[MAX_NO];
Rmq RMQ[20][3*MAX_NO];
var LOG[3*MAX_NO];
void euler(var node, var depth) {
    B[node] = ++tm;
    RMQ[0][tm] = Rmq(node, depth);
    for(auto vec : G[node]) {
        if(!B[vec]) {
            euler(vec, depth+1);
            RMQ[0][++tm] = Rmq(node, depth);
        }
    }
}

void build_log() {
    for(var i=2; i<=tm; i++) {
        LOG[i] = LOG[i/2] + 1;
    }
}
void build_rmq() {
    var n = tm;
    for(var i=1; (1<<i) <= n; i++) {
        for(var j=1; j+(1<<i)-1<=n; j++) {
            RMQ[i][j] = min(RMQ[i-1][j], RMQ[i-1][j+(1<<(i-1))]);
        }
    }
}

var lca(var a, var b) {
    a = B[a];
    b = B[b];
    if(a > b) swap(a, b);
    var l = LOG[b-a+1];
    Rmq r = min(RMQ[l][a], RMQ[l][b-(1<<l)+1]);
    return r.sol;
}

int main() {

    fin>>n>>m;
    for(var i=1; i<=n; i++) {
        for(var j=1; j<=n; j++) {
            fin>>A[i][j];
        }
    }
/*
    for(var i=1; i<=n; i++) {
        for(var j=1; j<=n; j++) {
            var t = toNod(i, j);

            var i1 = (t - 1) / n + 1;
            var j1 = (t - 1) % n + 1;

            fout<<i1<<" "<<j1<<" ; ";
        }
        fout<<endl;
    }
*/
    for(var i=1; i<n; i++) {
        for(var j=1; j<n; j++) {
            E.push_back(Edge(toNod(i, j), toNod(i+1, j), min(A[i][j], A[i+1][j])));
            E.push_back(Edge(toNod(i, j), toNod(i, j+1), min(A[i][j], A[i][j+1])));
        }
    }
    for(var i=1; i<n; i++) {
        E.push_back(Edge(toNod(n, i), toNod(n, i+1), min(A[n][i], A[n][i+1])));
        E.push_back(Edge(toNod(i, n), toNod(i+1, n), min(A[i][n], A[i+1][n])));
    }

    sort(E.begin(), E.end());
    var nodes = n*n;

    for(var i=1; i<=nodes; i++) {
        Node[i] = i;
    }

    for(auto e : E) {
        if(Find(e.a) != Find(e.b)) {

            PARENT[Node[Find(e.a)]] = PARENT[Node[Find(e.b)]] = ++nodes;

            G[nodes].push_back(Node[Find(e.a)]);
            G[nodes].push_back(Node[Find(e.b)]);


            COST[nodes] = e.c;

            Union(e.a, e.b, nodes);
        }
    }

    euler(nodes, 0);
    build_log();
    build_rmq();

    var a, b, c, d;

    while(m--) {
        fin>>a>>b>>c>>d;
        var u = toNod(a, b);
        var v = toNod(c, d);

        fout<<COST[lca(u, v)]<<'\n';
    }

    return 0;
}