AtCoder abc400_d Takahashi the Wall Breaker 题解 双端队列BFS
题目链接:https://atcoder.jp/contests/abc400/tasks/abc400_d
解题思路:
双端队列BFS(0-1 BFS)参考资料:https://oi.wiki/graph/bfs/#双端队列-bfs
比赛时我是用SPFA写的,然后TLE了一个点,然后用dijkstra AC了 dijkstra代码
因为状态转移的代价不是 0 就是 1,所以可以用 0-1 bfs。
比完赛寻思之前见过 0-1 bfs,寻思用 0-1 bfs 写一下。
0-1 bfs代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int n, m, sx, sy, ex, ey;
char s[maxn][maxn];
bool vis[maxn][maxn];
int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };
int dis[maxn][maxn];
bool in_map(int x, int y) {
return x >= 0 && x < n && y >= 0 && y < m;
}
struct Node {
int x, y;
};
void bfs01() {
deque<Node> que;
memset(dis, -1, sizeof dis);
dis[sx][sy] = 0;
que.push_back({sx, sy});
while (!que.empty()) {
Node u = que.front();
que.pop_front();
if (vis[u.x][u.y])
continue;
vis[u.x][u.y] = true;
for (int i = 0; i < 4; i++) {
for (int j = 1; j <= 2; j++) {
int x = u.x + dir[i][0] * j;
int y = u.y + dir[i][1] * j;
int w = 1;
if (j == 1 && in_map(x, y) && s[x][y] == '.')
w = 0;
if (!in_map(x, y))
continue;
if (dis[x][y] == -1 || dis[x][y] > dis[u.x][u.y] + w) {
dis[x][y] = dis[u.x][u.y] + w;
if (!w)
que.push_front({x, y});
else
que.push_back({x, y});
}
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
scanf("%s", s[i]);
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
sx--, sy--, ex--, ey--;
bfs01();
printf("%d\n", dis[ex][ey]);
return 0;
}