luogu P2895 [USACO08FEB]Meteor Shower S

题目大意

有一个矩形棋盘,某些格点在某时刻起不再能通行。从 ( 0 , 0 ) (0,0) (0,0) 开始以 1/s 的速度移动到一个永远安全的点,求最短时间。

解题思路

广度优先搜索即可。病历本:流星只能砸 300 以内,但人可以走 300 以外。

#include 
#include 
#include 

#define min(x,y) ((x)<(y)?(x):(y))

const int MAXM=50010;
const int MAXN=320;

struct node{
	int x, y;
	node (){
		x=y=0;
	}
}q[MAXN*MAXN*2];
int t[MAXN][MAXN], lmt[MAXN][MAXN];
int qd[MAXN][MAXN];	//是否在队列里 
int m;
int sx, sy, sz;
int ans=0x3f3f3f3f;

int fx[6]={0, 0, 0, -1, 1};
int fy[6]={0, -1, 1, 0, 0};

void update (int x, int y, int st){
	if (0>x||0>y||310nul");
		for (int i=1; i<=4; ++i){
			int nx=q[st].x+fx[i], ny=q[st].y+fy[i];
			if (0>nx||0>ny||310=lmt[nx][ny]) continue;
			if (lmt[nx][ny]>1e8) ans=min (ans, t[q[st].x][q[st].y]+1);
			if (t[nx][ny]>t[q[st].x][q[st].y]+1){
				t[nx][ny]=t[q[st].x][q[st].y]+1;
				if (!qd[nx][ny]){
					q[ed].x=nx; q[ed].y=ny;
					++ed; qd[nx][ny]=1;
				}
			}
		}
		qd[q[st].x][q[st].y]=0;
		++st;
	}
}
inline int read (){
	int s=0; char c;
	do c=getchar (); while ('0'>c||'9'=c)
		s=s*10+c-48, c=getchar ();
	return s;
}
int main (){
	memset (qd, 0, sizeof (qd));
	memset (t, 0x3f3f3f, sizeof (t)); t[0][0]=0;
	memset (lmt, 0x3f3f3f, sizeof (lmt));
	m=read ();
	for (int i=1; i<=m; ++i){
		sx=read (); sy=read (); sz=read ();
		for (int j=0; j<=4; ++j)
			update (sx+fx[j], sy+fy[j], sz);
	}
//	for (int i=0; i<=4; ++i){
//		for (int j=0; j<=4; ++j)
//			printf ("%d ", lmt[i][j]);
//		puts("");
//	}
	bfs ();
	if (ans>1e8) ans=-1;
	printf ("%d", ans);
}

你可能感兴趣的:(信息学,搜索,算法)