Cod sursa(job #1108318)

Utilizator superman_01Avramescu Cristian superman_01 Data 15 februarie 2014 16:18:08
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>


#define NMAX 305
#define QMAX 20005
 
using namespace std;
 
ifstream in ( "matrice2.in" );
ofstream out ( "matrice2.out" );
 
struct Query{
    int s_X, s_Y , f_X , f_Y , ind, Sol;
}Q[QMAX];
 
struct Cell{
    int x , y , v;
}C[NMAX*NMAX];
int TT[NMAX*NMAX] , RG[NMAX*NMAX], N , NR ;
int Map[NMAX][NMAX];
int dx[] = { -1 , 1 , 0 ,0  };
int dy[] = { 0 , 0 , -1 , 1 };
 
inline bool CompCell ( const Cell A , const Cell B )
{
    return A.v > B.v;
}
inline bool CompQueryV ( const Query  A , const Query B )
{
    return A.Sol > B.Sol;
}
inline bool CompQueryInd ( const Query A , const Query B )
{
    return A.ind < B.ind;
}
inline int Find ( int x )
{
    int y,R;
    for (  R = x ; R!=TT[R] ; R = TT[R] );
    for ( ; TT[x] != R ; )
    {
        y = TT[x];
        TT[y] = R ;
        x = y;
    }
    return R;
}
void MakeEdge(int Node1, int Node2)
{
    int x = Find(Node1) , y= Find(Node2);
    if (RG[x] > RG[y])
        TT[y] = x;
            else TT[x] = y;
  
    //in caz ca rangurile erau egale atunci cresc rangul noii multimi cu 1
    if (RG[x] == RG[y]) RG[y]++;
}
 
 inline void Try ( int x , int y )
{   
    int i ,newx , newy;
    TT[Map[x][y]] = Map[x][y];
    for ( i = 0 ; i < 4 ; ++i )
    {
        newx = x + dx[i] ;
        newy = y + dy[i] ;
        if ( TT[Map[newx][newy]] == 0 ) continue;
        MakeEdge ( Map[x][y] ,Map[newx][newy] );           
    }
}
 
int main ( void )
{

    int i , j , step , start;
    in >> N >> NR ;
    for ( i = 1 ; i <= N ; ++i )
        for ( j = 1 ; j <= N ; ++j )
        {
            Map[i][j] = ( i - 1) * N  + ( j - 1 ) + 1;
            C[Map[i][j]].x = i , C[Map[i][j]].y = j;
            in >> C[Map[i][j]].v;
        }
    for ( i = 1 ; i <= NR ; ++i )
        in >> Q[i].s_X >> Q[i].s_Y >> Q[i].f_X >> Q[i].f_Y , Q[i].ind = i;
	sort ( C + 1 , C + N * N + 1 , CompCell );
    for ( step = 20 ; step >= 0 ; --step )
    {
        memset ( TT , 0 , sizeof ( TT ) );
        sort ( Q + 1 , Q + NR + 1 , CompQueryV );
        for ( i = 1 , j = 1  ; i <= NR ; ++i )
        {
            for ( ; Q[i].Sol + ( 1<<step) <= C[j].v and j <= N *N ; ++j )
                Try ( C[j].x , C[j].y );
			int x = Find ( Map[Q[i].s_X][Q[i].s_Y] );  int y = Find ( Map[Q[i].f_X][Q[i].f_Y] );
			if ( x == y and x != 0 ) Q[i].Sol += (1<<step);
        }
    }
    sort ( Q + 1 , Q + NR + 1 , CompQueryInd );
    for ( i = 1 ; i <= NR ; ++i )
        out << Q[i].Sol << "\n";
    in.close();
    out.close();
    return 0 ;
}