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;
}
posted @ 2025-04-05 22:31  quanjun  阅读(153)  评论(0)    收藏  举报