UVA 11624 Fire! 【特殊BFS】
题意
人被困在迷宫里,有一些火苗在迷宫中会随时间蔓延,问人能否安全走到迷宫边界
分析
题本身很简单,只是这种题有两种处理方法:
- 火的状态很简单,只需要知道某个时间某个点有没有火,所以单独BFS一张火的图就可以了
- 一种比较巧妙的方法是,把火与人都当做BFS中的元素在一个队列中处理,注意BFS中同一层要先处理火,也就是最开始要先把火给入队
AC代码
(当时写的比较仓促,代码很丑……)
//UVA 11624 Fire!
//AC 2016-7-24 22:34:50
//BFS
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <list>
#include <sstream>
#include <stack>
using namespace std;
#define cls(x) memset(x,0,sizeof x)
#define inf(x) memset(x,0x3f,sizeof x)
#define neg(x) memset(x,-1,sizeof x)
#define ninf(x) memset(x,0xc0,sizeof x)
#define st0(x) memset(x,false,sizeof x)
#define st1(x) memset(x,true,sizeof x)
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define bug cout<<"here"<<endl;
//#define debug
int G[1500][1500];
int R,C;
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
vector<pair<int,int> > fires;
int fx,fy;
struct node
{
int x,y;
int steps;
bool isfire;
node(){}
node(int a,int b,int c):x(a),y(b),steps(c),isfire(0){}
bool operator< (const node &rhs) const
{
if(steps==rhs.steps)
return !isfire;
return steps>rhs.steps;
}
}p,q;
int visit[1500][1500];
int BFS(int sx,int sy)
{
if(sx==0||sx==R-1||sy==0||sy==C-1)
return 1;
inf(visit);
priority_queue<node> que;
for(int i=0;i<fires.size();++i)
{
node p(fires[i].first,fires[i].second,0);
p.isfire=1;
que.push(p);
}
que.push(node(sx,sy,0));
while(que.size())
{
p=que.top();
//cout<<p.x<<"--"<<p.y<<"--"<<p.steps<<endl;
que.pop();
if(p.isfire)
{
if(G[p.x][p.y]<p.steps)
continue;
else
G[p.x][p.y]=p.steps;
for(int i=0;i<4;++i)
{
q.x=p.x+dx[i];
q.y=p.y+dy[i];
q.steps=p.steps+1;
q.isfire=1;
if(q.x>=0&&q.x<R&&q.y>=0&&q.y<C&&G[q.x][q.y]>q.steps)
{
G[q.x][q.y]=q.steps;
que.push(q);
}
}
continue;
}
if(visit[p.x][p.y]<p.steps)
continue;
if(p.x==0||p.x==R-1||p.y==0||p.y==C-1)
return p.steps+1;
for(int i=0;i<4;++i)
{
q.x=p.x+dx[i];
q.y=p.y+dy[i];
q.steps=p.steps+1;
q.isfire=0;
if(q.x>=0&&q.y>=0&&q.x<R&&q.y<C&&q.steps<visit[q.x][q.y]&&q.steps<G[q.x][q.y])
{
visit[q.x][q.y]=q.steps;
que.push(q);
}
}
}
return -1;
}
int main()
{
#ifdef debug
freopen("E:\\Documents\\code\\input.txt","r",stdin);
freopen("E:\\Documents\\code\\output.txt","w",stdout);
#endif
int T=0;
scanf("%d",&T);
char c;
while(T--)
{
scanf("%d %d",&R,&C);
getchar();
inf(G);
int sx,sy;
fires.clear();
for(int i=0;i<R;++i)
{
for(int j=0;j<C;++j)
{
c=getchar();
if(c=='#')
G[i][j]=-1;
else if(c=='F')
{
G[i][j]=1;
fires.push_back(make_pair(i,j));
}
else
{
G[i][j]=INF;
if(c=='J')
{
sx=i;sy=j;
}
}
}
getchar();
}
int res=BFS(sx,sy);
if(res==-1)
printf("IMPOSSIBLE\n");
else
printf("%d\n",res);
}
return 0;
}