Cod sursa(job #191163)

Utilizator sima_cotizoSima Cotizo sima_cotizo Data 25 mai 2008 15:51:05
Problema Barbar Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.88 kb
#include <cstdio>
#include <queue>
#include <utility>
using namespace std;
#define MAX_SIZE 1024
#define INF 0x3fffff
typedef pair<int,int> ii;
#define mp make_pair
#define f first
#define s second

char Chars[MAX_SIZE][MAX_SIZE];
int A[MAX_SIZE][MAX_SIZE], Enq[MAX_SIZE][MAX_SIZE];
int R, C, i, j, m, step, sum, sol;
queue<ii> Q;
ii Start, Finish;

int dx[] = { 1, 0, 0, -1 };
int dy[] = { 0, 1,-1,  0 };

inline int ok(int x, int y) { return (x>=0 && x<R) && (y>=0 && y<C); }

int BFS_Test(int Limit) {
	int i, o = 0;
	memset( Enq, 0, sizeof(Enq) );

	Q.push( Start );
	while ( !Q.empty() ) {
		ii x = Q.front(); Q.pop();
		if ( x == Finish ) o = 1;
		for ( i=0; i<4; ++i ) {
			int nx = x.f+dx[i], ny = x.s+dy[i];
			if ( !ok(nx, ny) || A[nx][ny] < Limit ) continue;
			if ( !Enq[nx][ny] && !o ) Enq[nx][ny] = 1, Q.push( mp(nx,ny) );
		}
	}
	return o;
}

int main( ) {

	// load
	freopen( "barbar.in", "r", stdin );
	scanf("%d %d\n", &R, &C);
	for ( i=0; i<R; ++i ) 
		fgets( Chars[i], MAX_SIZE, stdin );

	// parse input
	for ( i=0; i<R; ++i )
		for ( j=0; j<C; ++j ) {
			A[i][j] = INF;
			switch ( Chars[i][j] ) {
				case 'D' : A[i][j] = 0; Q.push( mp(i,j) ); break;
				case 'I' : Start = mp(i,j); break;
				case 'O' : Finish = mp(i,j); break;
				case '*' : A[i][j] = -1; break;
			}
		}

	// initial BFS
	while ( !Q.empty() ) {
		ii x = Q.front(); Q.pop();
		for ( i=0; i<4; ++i ) {
			int nx = x.f + dx[i];
			int ny = x.s + dy[i];
			if ( !ok(nx, ny) ) continue;
			if ( A[nx][ny] > A[x.f][x.s] + 1 ) {
				A[nx][ny] = A[x.f][x.s] + 1;
				if ( !Enq[nx][ny] ) Q.push( mp(nx, ny) ), Enq[nx][ny] = 1;
			}
		}
		Enq[x.f][x.s] = 0;
		m = max( m, A[x.f][x.s] );
	}

	// restul
	for ( step=1; step<m; step<<=1 );
	for ( sum=0; ; step >>= 1 ) {
		int v = BFS_Test(sum+step);
		sum += v ? step : 0;
		sol |= v;

		if ( step==0 ) break;
	}

	fprintf(fopen("barbar.out", "w"), "%d\n", sum ? sum : -1);
	return 0;
}