Cod sursa(job #572608)

Utilizator AndrewTheGreatAndrei Alexandrescu AndrewTheGreat Data 5 aprilie 2011 14:40:57
Problema Matrice 2 Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <stdio.h>
#include <algorithm>
#include <vector>
#define pb push_back
#define TR(C, i)\
    for(i = C.begin(); i != C.end(); i++)


using namespace std;
const int nmax = 310;
const int Qmax = 20010;
int V[nmax * nmax], M[nmax][nmax], sir[nmax * nmax], Done[Qmax];
int N, Q, unde, TT[nmax * nmax], RG[nmax * nmax];

struct cmp
{
    bool operator()(const int &a, const int &b)const
    {
        return V[a] < V[b];
    }
};

struct pct
{
    int x, y;
};
pct coord[nmax * nmax], Query[Qmax][2];

vector<int>Quri[nmax][nmax];

void read()
{
    unde = 0;
    freopen ("matrice2.in", "r", stdin);
    freopen ("matrice2.out", "w", stdout);

    scanf("%d %d", &N, &Q);
    int i, j;
    for(i = 1; i <= N; i++)
        for(j = 1; j <= N; j++)
        {
            scanf("%d", &M[i][j]);
            sir[++unde] = unde;
            V[unde] = M[i][j];
            coord[unde].x = i;
            coord[unde].y = j;
            RG[unde] = 1;
            TT[unde] = unde;
        }

    sort(sir + 1, sir + 1 + N * N, cmp());

    for(i = 1; i <= Q; i++)
    {
        scanf("%d %d %d %d", &Query[i][0].x, &Query[i][0].y, &Query[i][1].x, &Query[i][1].y);
        Quri[Query[i][0].x][Query[i][0].y].pb(i);
        Quri[Query[i][1].x][Query[i][1].y].pb(i);
    }
}

vector<int> L;
int Viz[nmax][nmax];
int di[4] = {-1, 0, 0, 1},
    dj[4] = { 0,-1, 1, 0};

int find(int a)
{
    int R, t = a;
    while(a != TT[a])
        a = TT[a];

    while(t != TT[t])
    {
        R = TT[t];
        TT[t] = a;
        t = R;
    }
    return a;
}

void Unite(int a, int b)
{
    if(RG[a] > RG[b])
        TT[b] = a;
    else TT[a] = b;

    if(RG[a] == RG[b])
        RG[b]++;
}

void solve()
{
    vector<int>::iterator it;
    vector<int>::iterator t;
    int i, j;
    int undone = Q;
    for(i = unde; i > 0 && undone; i--)
    {
        Viz[coord[sir[i]].x][coord[sir[i]].y] = 1;
        for(j = 0; j < 4; j++)
            if( coord[sir[i]].x + di[j] <= N && coord[sir[i]].x + di[j] > 0
                && coord[sir[i]].y + dj[j] <= N && coord[sir[i]].y + dj[j] > 0
                && Viz[coord[sir[i]].x + di[j]][coord[sir[i]].y + dj[j]])
                Unite(find ( (coord[sir[i]].x - 1) * N + coord[sir[i]].y ), find((coord[sir[i]].x + di[j] - 1) * N + coord[sir[i]].y + dj[j]));

        TR(Quri[coord[sir[i]].x][coord[sir[i]].y], it)
        {
            Done[*it]++;
            if(Done[*it] == 2)
                L.pb(*it);
        }

        it = L.begin();
        while(it != L.end() && *it > 0)
        {
            if(find((Query[*it][0].x - 1) * N + Query[*it][0].y) ==
                find((Query[*it][1].x - 1) * N + Query[*it][1].y))
            {
               // t = it;
                Done[*it] = V[sir[i]];
                //it++;
                it = L.erase(it);
                undone--;
            }
            else it++;
        }
    }
    for(i = 1; i <= Q; i++)
        printf("%d\n", Done[i]);
}
int main()
{
    read();
    solve();
    return 0;
}