快速上手BFS入门例题

最短路径

回家

蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家。花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方。”

蒜头君希望能尽快回到家中,他需要首先取得任意一把钥匙,请你帮他计算出回家所需要的最短路程。

蒜头君生活的城市可以看做是一个n×m的网格,其中有道路有障碍,钥匙和家所在的地方可以看做是道路,可以通过。蒜头君可以在城市中沿着上下左右 44 个方向移动,移动一个格子算做走一步。

输入格式
第一行有两个整数 nn,mm。城市的地图是 nn行 mm 列。(1≤n,m≤2000)

接下来的 nn 行,每行 mm 个字符,代表城市的地图。’.’ 代表道路,’#’ 代表障碍物,‘S’ 代表蒜头君所在的位置,‘T’ 代表蒜头家的位置,'P’代表钥匙的位置。除了障碍物以外,别的地方都可以通过。(题目保证蒜头君至少有一条路径可以顺利拿到钥匙并且回家)

输出格式
输出蒜头回家要走的最少步数,占一行。

样例输入
8 10
P.####.#P#
…#…#…#
…#T##.#.#

…##.#####

#####…##
###…S##
样例输出
21

思路
先广搜至找到钥匙,设置flag进行状态标记。然后再次广搜。

#include <algorithm>
#include <iostream>
#include <queue>
using namespace std;
const int INF = 11111111;
typedef pair<int, int> point;
int res = INF + 1, n, m, book[100][100][2], dis[100][100];
char map[100][100];
int sx, sy;
int dx[4]{0, 1, 0, -1}, dy[4]{1, 0, -1, 0};
int flag = 0;
void bfs(int x, int y) {
    queue<point> q;
    q.push(point(x, y));
    book[x][y][0] = 1;
    while (q.size()) {
        point tmp = q.front();
        q.pop();
        if (map[tmp.first][tmp.second] == 'T' && flag) {
            res = min(res, dis[tmp.first][tmp.second]);
            return;
        }
        if (map[tmp.first][tmp.second] == 'P') {
            flag = 1;
        }
        for (int i = 0; i < 4; i++) {
            int xx = tmp.first + dx[i];
            int yy = tmp.second + dy[i];
            if (xx >= 0 && yy >= 0 && xx < n && yy < m && book[xx][yy][flag] == 0 &&
                map[xx][yy] != '#') {
                book[xx][yy][flag] = 1;
                q.push(point(xx, yy));
                dis[xx][yy] = dis[tmp.first][tmp.second] + 1;
            }
        }
    }
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> map[i][j];
            if (map[i][j] == 'S') {
                sx = i;
                sy = j;
            }
        }
    }
    fill(dis[0], dis[0] + 100 * 100, INF);
    dis[sx][sy] = 0;
    bfs(sx, sy);
    cout << res;
    return 0;
}

走迷宫最少步数

#include <iostream>
#include <queue>
using namespace std;
int step = 0;
int n, m, sx, sy, ex, ey;
char map[50][50];
int book[50][50];
int dist[50][50];
int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};
typedef pair<int, int> point;

int bfs(int x, int y) {
    queue<point> q;
    q.push(point(x, y));
    book[x][y] = 1;
    while (q.size()) {
        point temp = q.front();
        q.pop();
        book[temp.first][temp.second] = 1;
        if (map[temp.first][temp.second] == 'T')
            return dist[ex][ey];
        for (int i = 0; i < 4; i++) {
            int xx = temp.first + dx[i], yy = temp.second + dy[i];
            if (book[xx][yy] == 0 && map[xx][yy] != '#' && xx >= 0 && yy >= 0 && xx < n && yy < m) {
                book[xx][yy] = 1;
                q.push(point(xx, yy));
                dist[xx][yy] = dist[temp.first][temp.second] + 1;
            }
        }
    }
    return -1;
}

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> map[i][j];
            if (map[i][j] == 'S') {
                sx = i;
                sy = j;
            }
            if (map[i][j] == 'T') {
                ex = i;
                ey = j;
            }
        }
    }
    cout << bfs(sx, sy);
    return 0;
}

总结

需要的一般有map[],book[],dx[],dy[],dis[](用来记录距离),queue(容器)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值