链接:http://acm.hust.edu.cn/vjudge/problem/28833
题目大意:
一个人要逃出迷宫,同时可能有多个地方起火,火势向四周蔓延,火和人不能到达墙,人必须在火之前到达该格子,火和人的速度一样,求人逃出来的最短时间。
注意:对于人的bfs,最多搜索到最边界,但是走出迷宫还要一分钟,所以最后记得加1。
源代码:
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; #define inf 0x3f3f3f3f char m[1010][1010]; int vis[1010][1010]; int d[4][2]={1,0,-1,0,0,1,0,-1}; int dis[1010][1010]; int r,c,si,sj; struct node{ int x,y; int time; }; queue<node> q; queue<node> p; void bfsf() { while(!q.empty()) { node u=q.front(); q.pop(); for(int i=0;i<4;i++) { node v; v.x=u.x+d[i][0]; v.y=u.y+d[i][1]; if(v.x<0||v.x>=r||v.y<0||v.y>=c) continue; if(m[v.x][v.y]=='#') continue; if(vis[v.x][v.y]) continue; vis[v.x][v.y]=1; v.time=u.time+1; if(dis[v.x][v.y]>v.time) dis[v.x][v.y]=v.time; q.push(v); } } } int bfs() { memset(vis,0,sizeof(vis)); node u; u.x=si; u.y=sj;u.time=0; p.push(u); vis[u.x][u.y]=1; while(!p.empty()) { u=p.front(); p.pop(); if(u.x==0||u.x==r-1||u.y==0||u.y==c-1) return u.time; for(int i=0;i<4;i++) { node v; v.x=u.x+d[i][0]; v.y=u.y+d[i][1]; if(v.x<0||v.x>=r||v.y<0||v.y>=c) continue; if(m[v.x][v.y]=='#') continue; if(vis[v.x][v.y]) continue; v.time=u.time+1; if(v.time>=dis[v.x][v.y]) continue; vis[v.x][v.y]=1; p.push(v); } } return -1; } int main() { int T; scanf("%d",&T); while(T--) { memset(vis,0,sizeof(vis)); memset(dis,inf,sizeof(dis)); while (!p.empty()) p.pop(); //一定要记得清空队列! while (!q.empty()) q.pop(); scanf("%d%d",&r,&c); for(int i=0;i<r;i++) { for(int j=0;j<c;j++) { cin>>m[i][j]; if(m[i][j]=='J') { si=i; sj=j; } if(m[i][j]=='F') { node a; a.x=i;a.y=j;a.time=0; q.push(a); vis[i][j]=1; dis[i][j]=0; } } } bfsf(); int s=bfs()+1; if(!s) printf("IMPOSSIBLE\n"); else printf("%d\n",s); } return 0; }