搜索——最短路模型,多源bfs

2023-09-21 13:18:32

        最短路模型,即求从起点到终点的最短路径,我们可以选择dijkstra,spfa等等,在这里我们可以利用宽搜(bfs)的特性来求,因为bfs是一层一层的向外扩展的,所以当我们第一次遍历到终点时,所在的层数即为起点到终点的最短路径。

        多源bfs,顾名思义,多个起点的bfs,与一般的bfs不同的地方在于根据题目要求,将多个起点在初始时全部加入队列即可,后续遍历和普通bfs没什么不同。

1076. 迷宫问题 - AcWing题库

给定一个 n×n 的二维数组,如下所示:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

数据保证至少存在一条从左上角走到右下角的路径。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含 n 个整数 0 或 1,表示迷宫。

输出格式

输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。

按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 (0,0)(0,0),右下角坐标为 (n−1,n−1)。

数据范围

0≤n≤1000

输入样例:
5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
输出样例:
0 0
1 0
2 0
2 1
2 2
2 3
2 4
3 4
4 4

思路:简单bfs,要求输出路径,为了方便记录路径,我们从终点出发到起点,开辟一个二维数组记录一下每个点的前驱点即可

#include <iostream>
#include <cstring>
#include <algorithm>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;
int n;
int g[N][N];
PII q[N * N];
PII pre[N][N];//每个点的上一步

int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};

void bfs(int sx, int sy)
{
    int hh = -1, tt = -1;
    q[ ++ tt ] = {sx, sy};
    
    memset(pre, -1, sizeof pre);
    pre[sx][sy] = {0, 0};
    
    while (hh <= tt)
    {
        PII t = q[ ++ hh];
        
        for(int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if(a < 0 || a >= n || b < 0 || b >= n || g[a][b] || pre[a][b].x != -1) continue; 
            
            q[ ++ tt] = {a, b};
            pre[a][b] = t;
        }
        
    }
    
}

int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < n; j ++ )
            cin >> g[i][j];
            
    bfs(n - 1, n - 1);
            
    PII end = {0, 0};
    
    while (true)
    {
        printf("%d %d\n", end.x, end.y);
        if(end.x == n - 1 && end.y == n - 1) break;
        end = pre[end.x][end.y];
    }
            
    return 0;
}

173. 矩阵距离 - AcWing题库

给定一个 N 行 M 列的 0101 矩阵 A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为:

dist(A[i][j],A[k][l])=|i−k|+|j−l|

输出一个 N 行 M 列的整数矩阵 B,其中:

B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])

输入格式

第一行两个整数 N,M。

接下来一个 N 行 M 列的 0101 矩阵,数字之间没有空格。

输出格式

一个 N 行 M 列的矩阵 B,相邻两个整数之间用一个空格隔开。

数据范围

1≤N,M≤1000

输入样例:
3 4
0001
0011
0110
输出样例:
3 2 1 0
2 1 0 0
1 0 0 1

思路:将多个起点一起加入队列然后和普通bfs一样宽搜即可

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 1010;

int n, m;
char A[N][N];
int B[N][N];

void bfs()
{
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    
    memset(B, -1, sizeof B);
    
    queue<PII> q;
    for(int i = 0; i < n; i ++ )
        for(int j = 0; j < m; j ++ )
            if(A[i][j] == '1')
            {
                B[i][j] = 0;
                q.push({i, j});
            }
            
    while (q.size())
    {
        PII t = q.front();
        q.pop();
        
        for(int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if(a < 0 || a >= n || b < 0 || b >= m) continue;
            if(B[a][b] != -1) continue;
            
            B[a][b] = B[t.x][t.y] + 1;
            q.push({a, b});
        }
    }
}

int main()
{
    cin >> n >> m;
    for(int i = 0; i < n; i ++ ) cin >> A[i];
    
    bfs();
    
    for(int i = 0; i < n; i ++ )
    {
        for(int j = 0; j < m; j ++ ) cout << B[i][j] << " ";
        puts("");
    }
    
    return 0;
}

188. 武士风度的牛 - AcWing题库

1100. 抓住那头牛 - AcWing题库

更多推荐

华为云云耀云服务器L实例评测|基于L实例安装Prometheus+Grafana插件实现数据可视化监控

文章目录一、云耀云服务器介绍二、安装Prometheus创建prometheus.service配置文件启动prometheus服务查看prometheus服务进程三、安装node_exporter下载node_exporter组件包创建node_exporter.service配置文件启动node_exproter服

Docker 存储驱动解析:选择最适合你的存储方案

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

安果浏览器-这才是好用的安卓浏览器。

视频演示:安果浏览器,当之无愧的人民浏览器_哔哩哔哩_bilibili下载地址:安果移动☆一览无余的美观界面:深度优化的用户界面,为您带来简洁而不简单的浏览体验。无论是设计还是功能,安果浏览器都为您考虑到了细节。每一次滑动,每一个点击,都是为了给您带来更好的体验。☆秒速加载,畅快体验:厌倦了等待的时长?安果浏览器利用先

Java 字节流

一、输入输出流输入输出-------读写文件输入-------从文件中获取数据到自己的程序中,接收处理【读】输出-------将自己程序中处理好的数据保存到文件中【写】流-------数据移动的轨迹二、流的分类按照数据的移动轨迹分为:输入流输出流按照每一次读写/数据量的大小将流分成:字节流字符流字节流:每一次可读写一个

使用Canvas绘制一个验证码组件

使用Canvas绘制一个验证码组件前言验证码,这一日常伴随我们的要素,是我们在线交互的重要安全保障。你的手机短信里是否被它占据半壁江山,今天我们就来聊聊如何在网页上实现一个简单的验证码组件。大家在登录网站时为了防止被恶意攻击或者多次点击操作,使用验证码是最常用的实现方式。在学习完Canvas后,通过Canvas实现简单

Linux管理多版本node.js

这里介绍的是Linux版本的nvm工具:一个nodejs版本管理工具!这里可以灵活切换node指定版本哟~下载地址:https://github.com/nvm-sh/nvm/releases/1.安装需要先安装git、curlyuminstall-ygitcurl这里很慢,需要登录。如果不小心退出来,需要重新执行一下

AI绘画Stable Diffusion原理之扩散模型DDPM

前言传送门:stablediffusion:Git|论文stable-diffusion-webui:GitGoogleColabNotebook部署stable-diffusion-webui:GitkaggleNotebook部署stable-diffusion-webui:GitAI绘画,输入一段文本就能生成相关

xyhcms getshell

下载xyhcms3.6.2021版本并用phpstudy搭建functionget_cookie($name,$key=''){if(!isset($_COOKIE[$name])){returnnull;}$key=empty($key)?C('CFG_COOKIE_ENCODE'):$key;$value=$_CO

Naivcat 数据迁移工具 | 竟然那么香

近期,我们收到一位童鞋的留言(如下图),他建议我们多宣传Navicat的数据迁移工具,因为他身边许多小伙伴并非很了解这一功能。今天,我们为大家深度介绍Naivcat安全、可靠的数据迁移工具。请童鞋们准备好NavicatPremium工具,我们马上开始!数据库数据迁移是指选择、准备、提取和转换数据,并将数据从一个计算机存

孩子写作业买什么样台灯合适?适合孩子读写台灯推荐

现在孩子的普遍都存在视力问题,而导致孩子近视的原因可能跟光线太强或太弱、不用的用眼习惯、长时间的过度用眼等因素有关,根据数据表明目前中国近视患者人数达到6亿多,其中儿童青少年的视力不良率甚至高达八成,所以在孩子的学习道路上,护眼也是重中之重的事情。平时间养成良好的用眼习惯是必不可少的,不过照明光源的选择也重要,所以挑选

树莓派4b装系统到运行 Blazor Linux 本地程序全记录

在Linux下运行gui程序,咱也是第一次做,属于是瞎子过河乱摸一通,写得有什么不对和可以优化的地方,希望各位看官斧正斧正.##1.下载烧录器https://www.raspberrypi.com/software/####我选择的是Raspbian64位系统,并配置好ssh账号密码,wifi,以便启动后可以直接黑屏s

热文推荐