传送门:Safe Path
题意:问你能否从起始点到达出发点。注意,在地图的一些地区有怪兽,只要怪兽能在d步内到达你现在的位置,你会被立刻杀死。。
分析:BFS裸题,注意,N*M是2e5大小,把地图进行压缩一下~
代码如下:
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int INF = 1e9;
const int maxn = 2e5+233;
queue<int>que;
int dis[maxn];
bool vis[maxn];
int n,m,d;
int S,F,tot;
char s[maxn];
inline bool check(int x){
return x>=0 && x<n*m;
}
void bfs1(){
int dir[] = {-1,1,-m,m};
int now,tmp;
while (!que.empty()) {
now = que.front();
que.pop();
if (dis[now]>=d) continue;
for (int i=0; i<4; i++) {
tmp = dir[i]+now;
if (!check(tmp)) continue;
if (i<=1 && now/m != tmp/m) continue;
if (dis[now]+1>=dis[tmp]) continue;
dis[tmp] = dis[now]+1;
vis[tmp] = 1;
que.push(tmp);
}
}
}
int bfs2(){
int dir[] = {-1,1,-m,m};
while (!que.empty()) que.pop();
dis[S] = 0;
vis[S] = 1;
que.push(S);
int now,tmp;
while (!que.empty()) {
now = que.front();
que.pop();
if (now == F) return dis[now];
for (int i=0; i<4; i++) {
tmp = now + dir[i];
if (!check(tmp)) continue;
if (i<=1 && now/m != tmp/m) continue;
if (vis[tmp]) continue;
vis[tmp] = 1;
dis[tmp] = dis[now]+1;
que.push(tmp);
}
}
return -1;
}
int main(){
scanf("%d%d%d",&n,&m,&d);
memset(dis,0x7f,sizeof(dis));
memset(vis,0,sizeof(vis));
while (!que.empty()) que.pop();
tot = 0;
for (int i=0; i<n; i++) {
scanf("%s",s);
for (int j=0; j<m; j++) {
if (s[j]=='S') S = tot;
else if (s[j]=='F') F = tot;
else if (s[j]=='M') dis[tot] = 0, vis[tot] = 1,que.push(tot);
tot++;
}
}
bfs1();
if (vis[S] || vis[F]) { printf("-1\n"); return 0; }
printf("%d\n",bfs2());
return 0;
}