正解是两次bfs,先维护出火势蔓延到特定某个点的时间,因为这个是可以计算并且唯一的。
然后让joebfs,判断joe到这个点的时间小于火势到的时间,就可以通行。
我,废物,写了一个同时进行的,bfs。
并且wa了,写了one h,不想改了,待补。
错误代码:
#include <iostream> #include <math.h> #include <string.h> #include <vector> #include <map> #include <queue> #include <stdio.h> #include <algorithm> #include <cstdio> using namespace std; int n,m,flag[1005][1005],X1,Y1,book[1000001],ans,dx[5]={0,0,0,1,-1},dy[5]={0,1,-1,0,0},add,t; char maze[1005][1005]; struct node{ int x,y,cnt; }; queue<node>fire; queue<node>joe; void spread(int cnt) { int ok=1; while(!fire.empty( )&&ok==1) { node now; now=fire.front(); if(now.cnt>cnt) { ok=0;break; } else { fire.pop() ; for(int i=1;i<=4;i++) { int tx,ty; tx = now.x+dx[i]; ty = now.y+dy[i]; if(tx<=n&&tx>=1&&ty<=m&&ty>=1&&(maze[tx][ty]=='.'||maze[tx][ty]=='#')) { node son; son.x = tx; son.y = ty; son.cnt = now.cnt+1; maze[tx][ty]='F'; fire.push(son); } } } } return; } void bfs(int x,int y) { node start; start.x = x; start.y = y; start.cnt = 0; flag[x][y] = 1; joe.push(start); while(!joe.empty( )&&ans==0) { node now; now = joe.front( ); joe.pop( ); if(book[now.cnt] == 0) { spread(now.cnt); book[now.cnt]=1; add = now.cnt; } for(int i=1;i<=4;i++) { int tx,ty; tx = now.x+dx[i]; ty = now.y+dy[i]; if(tx<=n&&tx>=1&&ty<=m&&ty>=1&&flag[tx][ty]==0&&maze[tx][ty]=='.') { node son; son.x = tx; son.y = ty; son.cnt = now.cnt+1; joe.push(son); flag[tx][ty]=1; if(tx == n||tx == 1||ty == 1||ty == m) { ans=1; printf("%d\n",son.cnt+1); break; } } } } } void pre( ) { ans=0; memset(flag,0,sizeof(flag)); } void after(int cnt) { if(ans==0) { printf("IMPOSSIBLE\n"); } for(int i=0;i<=cnt+10;i++) { book[i]=0; } while(!joe.empty()) { joe.pop() ; } while(!fire.empty()) { fire.pop() ; } } int main( ) { //freopen("longlongcode.in","r",stdin); cin>>t; while(t--) { cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>maze[i][j]; if(maze[i][j]=='J') { X1=i;Y1=j; } if(maze[i][j]=='F') { node f; f.x = i; f.y = j; f.cnt = 0; fire.push(f); } } pre( ); bfs(X1,Y1); after(add); } }