【UVA11624】Fire!

題面

  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.

題意

  在一個nm 的網格圖中,有以下幾種類型的點:
  ①.‘#’,表示該網格不可以通過
  ②.‘.’,表示該網格可以通過
  ③.‘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(Tnk ),k 爲常數

代碼

#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;
                else
                    if( 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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章