当前位置: 代码迷 >> 综合 >> 【UVA11624】Fire!
  详细解决方案

【UVA11624】Fire!

热度:30   发布时间:2023-12-05 12:37:55.0

题面

??Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze.
??Given Joe’s location in the maze and which squares of the maze are on fire, you must determine whether Joe can exit the maze before the fire reaches him, and how fast he can do it.
??Joe and the fire each move one square per minute, vertically or horizontally (not diagonally). The fire spreads all four directions from each square that is on fire. Joe may exit the maze from any square that borders the edge of the maze. Neither Joe nor the fire may enter a square that is occupied by a wall.

题意

??在一个n?m的网格图中,有以下几种类型的点:
??①.‘#’,表示该网格不可以通过
??②.‘.’,表示该网格可以通过
??③.‘J’,表示J的起点
??④.‘F’,表示F的起点,F可能有多个起点
??JF每单位时间能够移动一格,当J到达网格边缘时可以在移动一次来脱离网格,F在不停地追赶J,请问J脱离网格至少要多少步?(可以认为F有无限个,即当前任意一个F所在格子的四联通块在下一单位时间内都可以有一个F

解法

bfs求最短路:
??首先从F的每一个起点出发,设gij表示F到达ij的最短时间,如果该格子为‘#’,那么g值为-1
求解完 g 值之后,从J的起点出发,设disij表示J到达该点的最短时间,如果该格子为‘#’,那么dis值为-1
??很容易看出,只有满足disijgij时,J才能够安全通过,所以判断一次即可

复杂度

O(T?n?k),k<script type="math/tex" id="MathJax-Element-11">k</script>为常数

代码

#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<queue>
#define Lint long long int
using namespace std;
const int INF=0x3f3f3f3f;
const int MAXN=1010;
struct node
{int x,y;
};
int dis[MAXN][MAXN];
int g[MAXN][MAXN];
int T,n,m;
queue<node> q;
int dx[5]={
   0,1,-1,0,0};
int dy[5]={
   0,0,0,1,-1};
void Prepare(int x,int y)
{node tmp;int tx,ty;g[x][y]=0;q.push( (node){ x,y } );while( !q.empty() ){tmp=q.front(),q.pop();for(int k=1;k<=4;k++){tx=tmp.x+dx[k],ty=tmp.y+dy[k];if( tx<1 || tx>n || ty<1 || ty>m || g[tx][ty]==-1 )   continue ;if( g[tx][ty]>g[tmp.x][tmp.y]+1 ){g[tx][ty]=g[tmp.x][tmp.y]+1;q.push( (node){ tx,ty } );}}}
}
void bfs(int x,int y)
{node tmp;int tx,ty;for(int i=1;i<=n;i++)   for(int j=1;j<=m;j++)   dis[i][j]=INF;dis[x][y]=0,q.push( (node){ x,y } );while( !q.empty() ){tmp=q.front(),q.pop();for(int k=1;k<=4;k++){tx=tmp.x+dx[k],ty=tmp.y+dy[k];if( tx<1 || tx>n || ty<1 || ty>m || g[tx][ty]==-1 )   continue ;if( dis[tmp.x][tmp.y]+1>=g[tx][ty] || dis[tmp.x][tmp.y]+1>=dis[tx][ty] )   continue ;dis[tx][ty]=dis[tmp.x][tmp.y]+1;q.push( (node){ tx,ty } );}}
}
int main()
{int sx,sy,cnt,ans;string s;scanf("%d",&T);node p[MAXN*10];while( T-- ){scanf("%d%d",&n,&m);ans=INF;sx=sy=cnt=0;memset( g,INF,sizeof g );for(int i=1;i<=n;i++){cin>>s;for(int j=0;j<=m-1;j++)if( s[j]=='J' )   sx=i,sy=j+1,g[i][j+1]=INF;elseif( s[j]=='F' )   p[++cnt]=(node){ i,j+1 };else   g[i][j+1]= s[j]=='#' ? -1 : INF ;}for(int i=1;i<=cnt;i++)   Prepare( p[i].x,p[i].y );bfs( sx,sy );for(int i=1;i<=n;i++)   ans=min( min( ans,dis[i][1] ),dis[i][m] );for(int i=1;i<=m;i++)   ans=min( min( ans,dis[1][i] ),dis[n][i] );printf( ans==INF ? "IMPOSSIBLE\n" : "%d\n",ans+1 );}return 0;
}