HDU 1072 NYOJ 483 Nightmare -- BFS+允许回头

/*
	有两种做法:
	一个不考虑走了回头路,因为数据是在是小,几乎不浪费时间
	另一个是用贪心策略,先假设所有点剩余时间为0,只要该点剩余时间小于 上一点剩余时间-1 
	则修改remain值为remain-1再入队,否则不入队
*/


#include 
#include 
#include 
#include 
#include 
using namespace std;
#define CLR(c,v) (memset(c,v,sizeof(c)))


const int M         = 30;
const int wall      = 0;
const int road      = 1;
const int start     = 2;
const int end       = 3;
const int reset     = 4;
const int bomblimit = 6;
int revise[][2]     = {{-1,0},
			       {0,-1},{0,1},
			          {1,0}};


int map[M][M];
int limit[M][M];
int n,m; // n*m

struct _P{
	int x,y;
	int step,remain;
	_P(int x=-1,int y=-1,int step=0,int remain=0):x(x),y(y),step(step),remain(remain){}
	bool operator <(const _P& p){
		return step > p.step;
	}
	bool operator ==(const _P& p){
		return (x==p.x) && (y==p.y);
	}
}S,E;
typedef _P NEXT;
typedef _P NOW;


int BFS(){
	queue<_P> que;
	que.push(S);
	while(!que.empty()){
		NOW now = que.front();
		que.pop();
		if (now == E){
			return now.step;
		}
		for (int i = 0 ; i < 4 ; i++){
			int nx = now.x + revise[i][0];
			int ny = now.y + revise[i][1];
			int re = now.remain - 1;
			if ( !(nx >= 0 && nx < n && ny >= 0 && ny < m ) || re <= 0)continue; // 出界 或 时间耗尽
			if (map[nx][ny] == wall)continue;

			NEXT next = NEXT( nx, ny, now.step+1, re );
			if (map[nx][ny] == reset){
				next.remain = bomblimit;
			}
			if (limit[nx][ny] < next.remain){ // 只有当剩余时间发现-1之后 还长的 才入队
				limit[nx][ny] = next.remain;
				que.push(next);
			}
		}
	}
	return -1;
}


int main(){
	//freopen("in.txt","r",stdin);
	//freopen("Input.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int Ncase,g;
	cin >> Ncase;
	while(Ncase -- ){
		cin >> n >> m;
		CLR(limit,0);
		for (int i = 0 ; i 

你可能感兴趣的:(【搜索】,【搜索】BFS)