Cod sursa(job #1081672)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 13 ianuarie 2014 20:17:41
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.76 kb
#include <fstream>
#include <algorithm>
#include <bitset>

using namespace std ;
const int Nmax = 305;
const int Mmax = 20004;
const int dx[] = { 1, 0, -1, 0};
const int dy[] = { 0, 1, 0, -1};

struct Element{
    int x, y, val;
    Element(){
        x = y = val = 0 ;
    }
    inline Element(const int _x,const int _y,const int _val){
        x = _x;
        y = _y;
        val = _val;
    }
    inline bool operator <(const Element A)const{
        return val > A.val;
    }
};
struct Query{
    int x0, y0, x, y, ind ,sol;
    Query(){
        x0 = y0 = x = y = ind = sol = 0;
    }
    inline Query(const int _x0,const int _y0,const int _x,const int _y,const int _ind){
        x0 = _x0;   y0 = _y0;
        x  = _x;    y  = _y;
        ind = _ind;
    }
    inline bool operator <(const Query A)const{
        return sol > A.sol;
    }
    inline bool operator ()(const Query A,const Query B)const{
        return A.ind < B.ind;
    }
};
int n, m;
int codif[Nmax][Nmax];
int Father[Nmax*Nmax];
bitset < Nmax > viz[Nmax]; 
Element element[Nmax*Nmax];
Query Q[Mmax];
inline void Read(){
    ifstream f("matrice2.in");
    f >> n >> m;
    int i, j, nr = 0 , x ,x0 ,y0, y;
    for(i = 1;i <= n; ++i){
        for(j = 1;j <= n; ++j){
            codif[i][j] = ++nr;
            f >> x;
            element[nr] = Element(i,j,x);
        }
    }
    for(i = 1;i <= m; ++i){
        f >> x0 >> y0 >> x >> y;
        Q[i] = Query(x0,y0,x,y,i);
    }
    f.close();
}

inline int Find(const int x){
    if(Father[x]!=x)
        Father[x] = Find(Father[x]);
    return Father[x];
}

inline void Unite(const int x,const int y){
    Father[x] = y;
}

inline void Solve(){
    int i, j,nr = n*n, k, d;
    int y, x, newx, newy;
    sort(element+1,element+nr+1);
    for(k = (1<<19) ; k; k /=2){//vom incerca sa adaugam k la solutiile query-urilor
        sort(Q+1,Q+m+1);
        for(i = 1;i <= nr; ++i)
            Father[i] = i;
        for(i =1; i <=  n; ++i)
            viz[i] = 0;
        for(i = 1,j = 1;j <= m; ++j){
            for( ; i <= nr && element[i].val >= Q[j].sol + k; ++i){
                x = element[i].x;
                y = element[i].y;
                viz[x][y] = 1;
                for(d = 0; d < 4; ++d){
                    newx = x + dx[d];
                    newy = y + dy[d];
                    if(viz[newx][newy]){
                        Unite(Find(codif[x][y]),Find(codif[newx][newy]));
                    }
                }
            }
            if(Find(codif[Q[j].x0][Q[j].y0])==Find(codif[Q[j].x][Q[j].y]))
                Q[j].sol += k;
        }
    }
}

inline void Write(){
    ofstream g("matrice2.out");
    sort(Q+1,Q+m+1,Query());
    for( int i = 1; i <= m; ++i)
        g<<Q[i].sol<<"\n";
    g.close();
}

int main(){
    Read();
    Solve();
    Write();
    return 0;
}