UVA - 11624
题意
简单的BFS运用,注意火源不止一个且火要比人先行动。
分别给火和人写一个队列就行了。
#pragma GCC optimize(3)//O3
#pragma GCC optimize(2)//O2
#include<bits/stdc++.h>
using namespace std;
using ll = long long ;
const int N = 1e3+19;
const int M = -999999;
int n,m;
char mp[N][N];
int vis[N][N];
int X[5]= {1,-1,0,0};
int Y[5]= {0,0,-1,1};
struct node
{
int x,y,tmp;
};
queue<node>F,J;
inline bool check(node k)
{
if(k.x<0||k.x>=n||k.y<0||k.y>=m||mp[k.x][k.y]=='#')
return true;
return false;
}
int BFS()
{
int cnt=1;
node f,j,k;
while(!J.empty())
{
while(!F.empty()&&F.front().tmp>=-cnt)//火先行动
{
f=F.front();
F.pop();
for(int i=0; i<4; ++i)
{
k.x=f.x+X[i];
k.y=f.y+Y[i];
k.tmp=f.tmp-1;
if(check(k)||vis[k.x][k.y]<0)
continue;
vis[k.x][k.y]=k.tmp;
F.push(k);
}
}
while(J.size()&&J.front().tmp<=cnt)
{
j=J.front();
J.pop();
if(j.x==0||j.x==n-1||j.y==0||j.y==m-1)//人到达边界
return j.tmp;
for(int i=0; i<4; ++i)
{
k.x=j.x+X[i];
k.y=j.y+Y[i];
k.tmp=j.tmp+1;
if(check(k)||vis[k.x][k.y])
continue;
vis[k.x][k.y]=k.tmp;
J.push(k);
}
}
cnt++;
}
return -1;
}
int work()
{
memset(vis,0,sizeof(vis));
while(!F.empty())
F.pop();
while(!J.empty())
J.pop();
node k;
for(int i=0; i<n; ++i)
{
for(int j=0; j<m; ++j)
{
if(mp[i][j]=='J')
{
k.x=i,k.y=j,k.tmp=1;
vis[i][j]=1;//人的标记采用正数
J.push(k);
}
else if(mp[i][j]=='F')
{
k.x=i,k.y=j,k.tmp=-1;
vis[i][j]=-1;//火的标记采用负数
F.push(k);
}
}
}
return BFS();
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin>>t;
while(t--)
{
cin>>n>>m;
for(int i=0; i<n; ++i)
cin>>mp[i];
int ans=work();
if(ans==-1)
cout<<"IMPOSSIBLE\n";
else
cout<<ans<<endl;
}
return 0;
}