1.模板
#include <bits/stdc++.h>
using namespace std;
// 深度优先搜索
void dfs(int u, vector<bool>& visited, const vector<vector<int>>& matrix) {
visited[u] = true;
cout << u << " ";
for (int v = 0; v < matrix[u].size(); ++v) {
if (matrix[u][v] && !visited[v]) {
dfs(v, visited, matrix);
}
}
}
// 广度优先搜索
void bfs(int start, vector<bool>& visited, const vector<vector<int>>& matrix) {
queue<int> q;
q.push(start);
visited[start] = true;
while (!q.empty()) {
int u = q.front();
q.pop();
cout << u << " ";
for (int v = 0; v < matrix[u].size(); ++v) {
if (matrix[u][v] && !visited[v]) {
visited[v] = true;
q.push(v);
}
}
}
}
int main() {
// 读入矩阵的长和宽
int n, m;
cout << "矩阵的长和宽是: ";
cin >> n >> m;
// 读入矩阵的内容
vector<vector<int>> matrix(n, vector<int>(m));
cout << "输入矩阵的内容:" << endl;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cin >> matrix[i][j];
}
}
// 初始化访问标记数组
vector<bool> visited(n, false);
// 从顶点0开始进行 DFS 和 BFS
cout << "DFS : ";
dfs(0, visited, matrix);
cout << endl;
// 重置访问标记数组
fill(visited.begin(), visited.end(), false);
cout << "BFS : ";
bfs(0, visited, matrix);
cout << endl;
return 0;
}
这个模板可以处理无向图。如果要处理有向图,只需删除 BFS 和 DFS 函数中的一行
adj[v].push_back(u);
即可。
2.例题
题目描述
小红来到了一个n∗mn*mn∗m的矩阵,她初始站在左上角,每次行走可以按“上下左右”中的一个方向走一步,但必须走到和当前格子不同的字符,也不能走到矩阵外。
小红想知道,从左上角走到右下角最少需要走多少步?
输入描述:
第一行输入两个正整数n,mn,mn,m,用空格隔开。代表矩阵的行数和列数。
接下来的nnn行,每行输入一个长度为mmm的、仅由小写字母组成的字符串,用来表示矩阵。
1≤n,m≤10001\leq n,m \leq10001≤n,m≤1000
输出描述:
如果无法到达右下角,则输出-1。 否则输出一个整数,代表行走的最小步数。
输入
3 4 abbc accd bcee
输出
9
说明
2.1题解代码
#include <bits/stdc++.h>
using namespace std;
// 定义节点结构
struct Node {
int x, y, steps; // 节点的 x 和 y 坐标,以及到达该节点的步数
};
// 定义四个方向的移动
int dx[] = {-1, 1, 0, 0}; // 上下左右
int dy[] = {0, 0, -1, 1};
// 使用 BFS 算法找到从左上角到右下角的最短路径的步数
int bfs(vector<vector<char>>& matrix, int n, int m) {
queue<Node> q; // 定义队列存储待访问的节点
vector<vector<bool>> visited(n, vector<bool>(m, false)); // 标记节点是否已访问
q.push({0, 0, 0}); // 将起点加入队列,并初始化步数为 0
visited[0][0] = true; // 标记起点已访问
while (!q.empty()) {
Node curr = q.front(); // 获取队列中的当前节点
q.pop(); // 弹出队列中的当前节点
if (curr.x == n - 1 && curr.y == m - 1) { // 如果当前节点是终点,则返回到达终点的步数
return curr.steps;
}
for (int i = 0; i < 4; i++) { // 遍历四个方向
int nx = curr.x + dx[i]; // 计算下一个节点的 x 坐标
int ny = curr.y + dy[i]; // 计算下一个节点的 y 坐标
if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] &&
matrix[nx][ny] != matrix[curr.x][curr.y]) { // 如果下一个节点在矩阵范围内且未被访问过,并且与当前节点的值不同(不是障碍物)
q.push({nx, ny, curr.steps + 1}); // 将下一个节点加入队列,并更新步数
visited[nx][ny] = true; // 标记下一个节点已访问
}
}
}
return -1; // 如果无法到达终点,则返回 -1
}
int main() {
int n, m;
cin >> n >> m; // 输入矩阵的行数和列数
vector<vector<char>> matrix(n, vector<char>(m)); // 定义矩阵
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cin >> matrix[i][j]; // 输入矩阵的每个元素值
}
}
int steps = bfs(matrix, n, m); // 调用 BFS 算法计算最短路径步数
cout << steps << endl; // 输出最短路径步数
return 0;
}