先對火BFS一次,求出每個點的最小著火時間。
再對人BFS一次,求出走到邊界的最少時間。
#include <iostream> #include <queue> #include <cstring> using namespace std; int n,m,bz[1005][1005],qihuo[1005][1005]; char map[1005][1005]; int h[4][2]={-1,0,1,0,0,-1,0,1}; struct point { int x,y,step; }; queue<point> q; void bfs_huo() { int i,j,x,y; point t,tt; while(!q.empty()) { t=q.front(); q.pop(); for(i=0;i<4;i++) { x=t.x+h[i][0]; y=t.y+h[i][1]; if(x>=0&&x<n&&y>=0&&y<m&&(map[x][y]=='.'||map[x][y]=='J')&&!bz[x][y]) { bz[x][y]=1; tt.x=x; tt.y=y; tt.step=t.step+1; qihuo[x][y]=tt.step; q.push(tt); } } } } int bfs_men(point s) { int i,j,x,y; point t,tt; while(!q.empty()) q.pop(); q.push(s); bz[s.x][s.y]=1; while(!q.empty()) { t=q.front(); q.pop(); if(t.x<=0||t.x==n-1||t.y<=0||t.y==m-1) return t.step; //??磬?0 for(i=0;i<4;i++) { x=t.x+h[i][0]; y=t.y+h[i][1]; if(x>=0&&x<n&&y>=0&&y<m&&(map[x][y]=='.'||map[x][y]=='J')&&!bz[x][y]) { if(qihuo[x][y]<=t.step+1) continue; bz[x][y]=1; tt.x=x; tt.y=y; tt.step=t.step+1; q.push(tt); } } } return -1; } int main(int argc, char *argv[]) { int nn,i,j; point s,t; cin>>nn; while(nn--) { cin>>n>>m; while(!q.empty()) q.pop(); memset(bz,0,sizeof(bz)); for(i=0;i<n;i++) for(j=0;j<m;j++) { cin>>map[i][j]; qihuo[i][j]=1000000000; //??? if(map[i][j]=='J') {s.x=i; s.y=j; s.step=0;} if(map[i][j]=='F') {t.x=i; t.y=j; t.step=0; q.push(t); bz[i][j]=1; qihuo[i][j]=0;} } bfs_huo(); memset(bz,0,sizeof(bz)); int ans=bfs_men(s); if(ans>=0) cout<<ans+1<<endl; else cout<<"IMPOSSIBLE"<<endl; } return 0; }