c++实现的深度优先遍历(dfs)和广度优先遍历(bfs)模板以及例题分析

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值