题目链接:http://uva.onlinejudge.org/external/116/11624.pdf
题意:给定一个迷宫和一些着火点,火会不断想四周蔓延,求一条逃出迷宫的最短路径。
思路:先用一次BFS求出火蔓延到每个点的最短时间,可以把#的时间设为0,'.'火到不了的,设为oo(这里应该注意一下,WA了一次)。后面就是常规的BFS求最短路了。
代码:
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#define LL long long
#define INF 0x7fffffff
using namespace std;
struct node{
int x,y,step;
};
char Map[1010][1010];
int vis[1010][1010],dis[1010][1010];
int R,C,J[2];
vector<int> F;
int d[][2]={1,0,-1,0,0,-1,0,1};
void bfs(){//求出火蔓延到每个点的时间
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(dis));
queue<node> Q;
for(int i=0;i<(int)F.size();i++)
Q.push((node){F[i]/R,F[i]%R,0}),vis[F[i]/R][F[i]%R]=1;
while(!Q.empty()){
node tp=Q.front();
Q.pop();
for(int p=0;p<4;p++){
int tx=tp.x+d[p][0],ty=tp.y+d[p][1];
if(tx<0 || ty<0 || tx>=R || ty>=C) continue;
if(Map[tx][ty]!='.' || vis[tx][ty]) continue;
dis[tx][ty]=tp.step+1;
Q.push((node){tx,ty,tp.step+1});
vis[tx][ty]=1;
}
}
for(int i=0;i<R;i++) for(int j=0;j<C;j++)//火蔓延不到的点且为通行路径,时间置为oo
if(Map[i][j]=='.' && !vis[i][j]) dis[i][j]=INF;
}
void BFS(){//现在就是常规的BFS求最短路了
memset(vis,0,sizeof(vis));
queue<node> Q;
Q.push((node){J[0],J[1],0});
vis[J[0]][J[1]]=1;
while(!Q.empty()){
node tp=Q.front();
if(tp.x==0 || tp.y==0 || tp.x==R-1 || tp.y==C-1) {cout<<tp.step+1<<endl;return;}
Q.pop();
for(int p=0;p<4;p++){
int tx=tp.x+d[p][0],ty=tp.y+d[p][1];
if(tx<0 || ty<0 || tx>=R || ty>=C) continue;
if(vis[tx][ty] || tp.step+1>=dis[tx][ty]) continue;
vis[tx][ty]=1;
Q.push((node){tx,ty,tp.step+1});
}
}
cout<<"IMPOSSIBLE\n";
}
int main(){
//freopen("D:\\in.txt","r",stdin);
int T;cin>>T;
while(T--){
cin>>R>>C; F.clear();
getchar();
for(int i=0;i<R;i++){
for(int j=0;j<C;j++){
scanf("%c",&Map[i][j]);
if(Map[i][j]=='J') J[0]=i,J[1]=j;
else if(Map[i][j]=='F') F.push_back(i*R+j);
}
getchar();
}
bfs();
BFS();
}
return 0;
}