Cod sursa(job #931751)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 28 martie 2013 14:37:32
Problema Matrice 2 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <fstream>
#include <algorithm>
#define nmax 200100
#define qmax 20100
#define mmax 310
#define nod(x,y) ((x<<9)|y)
#define First(x) (x>>9)
#define Second(x) (x&((1<<9)-1))
using namespace std;

struct punct{int Nod,Value;}Punct[nmax];
struct query{int A,B,Index,Answer;}Query[qmax];

int Dx[]={0,0,0,-1,1},Dy[]={0,-1,1,0,0};
int N,Nr,Q,Father[nmax],A[mmax][mmax];

bool comparePunctValue(punct X,punct Y) {

    return X.Value>Y.Value;

}
bool compareQueryIndex(query X,query Y) {

    return X.Index<Y.Index;

}
bool compareQueryAnswer(query X,query Y) {

    return X.Answer>Y.Answer;

}
void Unite(int A,int B) {

	Father[B]=A;

}
int Root(int Nod) {

	if(Father[Nod]!=Nod)
		return Father[Nod]=Root(Father[Nod]);
	return Nod;

}
void Expand(int Nod,int Min) {

    int i,v,w,X,Y;

    v=Root(Nod);

    for(i=1;i<=4;i++) {

        X=First(Nod)+Dx[i];
        Y=Second(Nod)+Dy[i];

        if(A[X][Y]==-1 || A[X][Y]<Min)
            continue;

        w=Root(nod(X,Y));

        if(v!=w)
            Unite(v,w);

        }

}
void initialiseForest() {

    for(int i=1;i<=nod(N,N);i++)
        Father[i]=i;

}
void bordare() {

    for(int i=0;i<=N+1;i++)
        A[i][0]=A[i][N+1]=A[0][i]=A[N+1][i]=-1;

}
void solve() {

	int i,k,Step,Min;

	Nr=N*N;
	sort(Punct+1,Punct+Nr+1,comparePunctValue);
	bordare();

	for(Step=(1<<20);Step;Step>>=1) {

	    sort(Query+1,Query+Q+1,compareQueryAnswer);
	    initialiseForest();

	    for(i=k=1;i<=Q;i++) {

	        Min=Query[i].Answer+Step;

	        for(;k<=Nr && Punct[k].Value >= Min;k++)
                Expand(Punct[k].Nod,Min);

            if(Root(Query[i].A) == Root(Query[i].B))
                Query[i].Answer = Min;

            }

        }

}
void read() {

	int i,j,x,y;
	ifstream in("matrice2.in");
	in>>N>>Q;

	for(i=1;i<=N;i++)
		for(j=1;j<=N;j++) {

			in>>A[i][j];
			Punct[(i-1)*N+j].Nod=nod(i,j);
			Punct[(i-1)*N+j].Value=A[i][j];

			}

    for(i=1;i<=Q;i++) {

        in>>x>>y;
        Query[i].A=nod(x,y);
        in>>x>>y;
        Query[i].B=nod(x,y);

        Query[i].Index=i;

        }

    in.close();

}
void write() {

    ofstream out("matrice2.out");

    sort(Query+1,Query+Q+1,compareQueryIndex);

    for(int i=1;i<=Q;i++)
        out<<Query[i].Answer<<'\n';

    out.close();

}
int main() {

	read();
	solve();
	write();

	return 0;

}