📜  使用STL进行竞争编码的BFS(1)

📅  最后修改于: 2023-12-03 14:49:51.744000             🧑  作者: Mango

使用STL进行竞争编码的BFS

BFS(Breadth First Search)是一种基础的图遍历算法,常用于解决广度优先搜索问题。在竞争编程中,BFS 是一种常见的解法,能够在较短时间内找到最短路径和其他优秀的解答。使用 C++ 的 STL(STL即标准模板库,它是C++中内置的一个重要的库,提供了丰富的数据结构和算法) 可以大大简化 BFS 的实现。

实现

下面是一个示例代码片段,它使用 STL 中的 queue 和 vector 来实现 BFS。我们以求解“Maze”迷宫问题为例,在迷宫中寻找一条从起点到终点的最短路径。

#include <iostream>
#include <queue>
#include <vector>
using namespace std;

const int MAX_N = 1000;
const int MAX_M = 1000;
int maze[MAX_N][MAX_M];
bool visited[MAX_N][MAX_M];
int N, M;

const int dx[4] = {0, 1, 0, -1};  // 右、下、左、上四个方向的偏移值
const int dy[4] = {1, 0, -1, 0};

struct Node {
    int x;
    int y;
    int step;

    Node(int x, int y, int step) : x(x), y(y), step(step) {}
};

int bfs() {
    queue<Node> q;
    q.push(Node(0, 0, 0));
    visited[0][0] = true;

    while (!q.empty()) {
        Node node = q.front();
        q.pop();

        if (node.x == N - 1 && node.y == M - 1) {
            return node.step;
        }

        for (int i = 0; i < 4; i++) {
            int nx = node.x + dx[i];
            int ny = node.y + dy[i];

            if (nx >= 0 && nx < N && ny >= 0 && ny < M && maze[nx][ny] == 0 && !visited[nx][ny]) {
                q.push(Node(nx, ny, node.step + 1));
                visited[nx][ny] = true;
            }
        }
    }

    return -1;  // 找不到路径
}

int main() {
    // 输入迷宫
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> maze[i][j];
        }
    }

    // 计算最短路径
    int ans = bfs();

    // 输出结果
    cout << ans << endl;

    return 0;
}
解释

首先声明两个常量 MAX_N 和 MAX_M,分别表示迷宫的最大行数和列数。对于每个位置,我们使用 maze 数组表示其状态,0 表示可通过,1 表示障碍物。visited 数组表示该位置是否被访问过。N 和 M 表示迷宫的行数和列数。

const int MAX_N = 1000;
const int MAX_M = 1000;
int maze[MAX_N][MAX_M];
bool visited[MAX_N][MAX_M];
int N, M;

定义结构体 Node,表示 BFS 中的一个节点。其中包含了 x 和 y 两个参数,分别表示当前位置的行列坐标,step 参数表示到达该位置的步数。

struct Node {
    int x;
    int y;
    int step;

    Node(int x, int y, int step) : x(x), y(y), step(step) {}
};

定义四个常量 dx 和 dy,表示四个方向上的偏移量。

const int dx[4] = {0, 1, 0, -1};  // 右、下、左、上四个方向的偏移值
const int dy[4] = {1, 0, -1, 0};

定义一个 bfs() 函数,用来计算起点到终点的最短路径。在函数开头,我们首先创建了一个队列 q,将起点加入队列。同时也将起点标记为已访问。

int bfs() {
    queue<Node> q;
    q.push(Node(0, 0, 0));
    visited[0][0] = true;

然后就是常规 BFS 的过程:每次取出队头元素,从它的上下左右四个方向分别进行扩展。如果扩展出来的点满足条件(未访问过、能通过),则加入队列,并标记为已访问。

while (!q.empty()) {
    Node node = q.front();
    q.pop();

    if (node.x == N - 1 && node.y == M - 1) {
        return node.step;
    }

    for (int i = 0; i < 4; i++) {
        int nx = node.x + dx[i];
        int ny = node.y + dy[i];

        if (nx >= 0 && nx < N && ny >= 0 && ny < M && maze[nx][ny] == 0 && !visited[nx][ny]) {
            q.push(Node(nx, ny, node.step + 1));
            visited[nx][ny] = true;
        }
    }
}

最后,我们在 main 函数的开头读入迷宫的行列数,以及迷宫的状态,计算出最短路径并输出。

int main() {
    // 输入迷宫
    cin >> N >> M;
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++) {
            cin >> maze[i][j];
        }
    }

    // 计算最短路径
    int ans = bfs();

    // 输出结果
    cout << ans << endl;

    return 0;
}
总结

使用 STL 进行竞争编程的 BFS 算法能够大大简化代码的编写过程,提高代码的可读性和可维护性,还能减少可能出现的 bug。虽然学习 STL 也需要一定的时间和精力,但是在实际应用中,STL 的效率和强大的功能远超过了其所带来的学习成本。建议不熟悉 STL 的程序员可以多加练习,提高熟练度。