UVA 11624 Fire!(两次BFS+记录最小着火时间)

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671

题目大意:一个n*m迷宫,迷宫中有一个点'J'是人也就是起点,有多个点'F'表示着火,人每秒都可以往水平或垂直方向走,火势也可以往水平或垂直方向蔓延,火和人都不能过'#',但可以过‘.’。问人最后能否从迷宫逃出,不被火烧到。

解题思路:两次bfs,第一次求各点被火烧到的最小时间用step[x][y]记录,如果烧不到就是inf。第二次bfs,求从起点能否逃出迷宫,但是比如说下一步走到(x,y)时间是t,t如果>=step[x][y]则这个点不能走,因为走到这里时,这里已经备火势蔓延了。注意:有多个着火点,看了我两个小时。气死我了啊啊啊!!!

代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<queue>
  4 using namespace std;
  5 const int N=1e3+5;
  6 const int inf=0x3f3f3f3f;
  7 
  8 struct node{
  9     int x,y,step;
 10 }pre,now;
 11 
 12 int m,n,ans,cnt,x1,y1;
 13 int d[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
 14 char map[N][N];
 15 int vis[N][N],step[N][N];//step[x][y]记录被各点烧到的最短时间 
 16 
 17 struct node2{
 18     int x,y;
 19 }point[N*N];
 20 
 21 //求着火时间 
 22 void bfs1(){
 23     queue<node>q;
 24     for(int i=1;i<=cnt;i++){
 25         int x=point[i].x;
 26         int y=point[i].y;
 27         now.x=x;
 28         now.y=y;
 29         now.step=0;
 30         step[x][y]=0;
 31         q.push(now);
 32     }
 33     while(!q.empty()){
 34         pre=q.front();
 35         q.pop();
 36         for(int i=0;i<4;i++){
 37             int xx=pre.x+d[i][0];
 38             int yy=pre.y+d[i][1];
 39             int t=pre.step+1;
 40             if(xx<1||yy<1||xx>n||yy>m||map[xx][yy]=='#'||step[xx][yy]!=inf)
 41                 continue;
 42             step[xx][yy]=t;
 43             now.x=xx;
 44             now.y=yy;
 45             now.step=t;    
 46             q.push(now);
 47         }
 48     }
 49 }
 50 //求是否能逃出去 
 51 bool bfs2(){
 52     queue<node>q;
 53     now.x=x1;
 54     now.y=y1;
 55     now.step=0;
 56     q.push(now);
 57     while(!q.empty()){
 58         pre=q.front();
 59         q.pop();
 60         for(int i=0;i<4;i++){
 61             int xx=pre.x+d[i][0];
 62             int yy=pre.y+d[i][1];
 63             int t=pre.step+1;
 64             if(t>=step[xx][yy]||map[xx][yy]=='#'||vis[xx][yy])
 65                 continue;
 66             if(xx<1||yy<1||xx>n||yy>m){
 67                 ans=t;
 68                 return true;
 69             }
 70             vis[xx][yy]=1;
 71             now.x=xx;
 72             now.y=yy;
 73             now.step=t;
 74             q.push(now);
 75         }
 76     }
 77     return false;
 78 }
 79 
 80 int main(){
 81     int T;
 82     scanf("%d",&T);
 83     while(T--){
 84         cnt=0;
 85         memset(vis,0,sizeof(vis));
 86         memset(step,0x3f,sizeof(step));
 87         memset(map,'.',sizeof(map));
 88         scanf("%d%d",&n,&m);    
 89         for(int i=1;i<=n;i++){
 90             getchar();
 91             for(int j=1;j<=m;j++){
 92                 scanf("%c",&map[i][j]);
 93                 if(map[i][j]=='F'){
 94                     point[++cnt].x=i;
 95                     point[cnt].y=j;
 96                 }
 97                 if(map[i][j]=='J')
 98                     x1=i,y1=j;
 99             }
100         }
101         bfs1();
102         if(!bfs2())
103             puts("IMPOSSIBLE");
104         else
105             printf("%d\n",ans);
106     }
107     return 0;
108 }

 

posted @ 2017-09-15 17:47  Yeader  阅读(239)  评论(0编辑  收藏  举报