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 }