算法笔记(十四)——多源 BFS

news2024/10/9 8:51:03

文章目录

  • <font color=red>01 矩阵
  • <font color=red>飞地的数量/font>
  • 地图中的最高点
  • 地图分析

多源 BFS

单源最短路问题:一个起点到一个终点的最短路;
解决步骤:

  • 把起点放进队列里
  • 一层一层往外扩

相关文章:算法笔记(十三)——BFS 解决最短路问题

多源最短路问题:多个起点到同一个终点的最短路;

多源BFSBFS来解决多源最短路问题

如何解决???

  • 把所有源点当成一个源点 <==> 单一的最短路问题

解决步骤

  • 把所有起点放进队列里
  • 一层一层往外扩

01 矩阵

题目:01 矩阵

在这里插入图片描述
思路

1当作起点,0当作终点的话,我们逆推起点比较麻烦,所以我们反着想;将0当作起点,1当作终点,这样就可以直接将答案填在答案数组的终点位置中;

  • 遍历原数组将所有0放入队列
  • 一层一层向外拓展

C++代码

class Solution 
{
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
public:
    vector<vector<int>> updateMatrix(vector<vector<int>>& mat) 
    {
        int m = mat.size(), n = mat[0].size();
        vector<vector<int>> ret(m, vector<int>(n, -1));
        queue<pair<int,int>> q;

        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(mat[i][j] == 0)
                {
                    q.push({i, j});
                    ret[i][j] = 0;
                }

        while(!q.empty())
        {
            auto [a, b] = q.front();
            q.pop();
            for(int i = 0; i < 4; i++)
            {
                int x = a + dx[i], y = b + dy[i]; 
                if(0 <= x && x < m && 0 <= y && y < n && ret[x][y] == -1)
                {
                    ret[x][y] = ret[a][b] + 1;
                    q.push({x, y});
                }
            }
        }

        return ret;
    }
};

飞地的数量/font>

题目:飞地的数量

在这里插入图片描述
思路

逆向思维

(单源BFS) 从边缘开始以1为起点开始单源BFS当遇到1时,将其更改为0

(单源BFS) 从边缘的1进行遍历
最后遍历原数组grid,其中1的个数为答案,即无法出去的数量

C++代码(单源BFS)

class Solution 
{
    const int dx[4]={0,0,1,-1};
    const int dy[4]={-1,1,0,0};
    int m, n;
    queue<pair<int, int>> q;
    void bfs(vector<vector<int>>& grid, int i, int j)
    {
        q.push({i, j});
        grid[i][j] = 0;

        while(!q.empty())
        {
            int sz = q.size();
            for(int i = 0; i < sz; i++)
            {
                auto [a, b] = q.front();
                q.pop();
                for(int k = 0; k < 4; k++)
                {
                    int x = a + dx[k], y = b + dy[k];
                    if(0 <= x && x < m && 0 <= y && y < n && grid[x][y] == 1)
                    {
                        grid[x][y] = 0;
                        q.push({x, y});
                    }
                }
            }
        }
    }
public:
    int numEnclaves(vector<vector<int>>& grid) 
    {
        m = grid.size(), n = grid[0].size();
        for(int i = 0; i < m; i++)
        {
            if(grid[i][0] == 1) bfs(grid, i, 0);
            if(grid[i][n - 1] == 1) bfs(grid, i, n - 1);
        }
        for(int i = 1; i < n - 1; i++)
        {
            if(grid[0][i] == 1) bfs(grid, 0, i);
            if(grid[m - 1][i] == 1) bfs(grid, m - 1, i);
        }

        int ret = 0;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(grid[i][j] == 1) ret += 1;
        
        return ret;
    }
};

C++代码(多源BFS)

class Solution 
{
    // 定义四个方向的坐标变化
    const int dx[4] = {0, 0, 1, -1};
    const int dy[4] = {1, -1, 0, 0};

public:
    int numEnclaves(vector<vector<int>>& grid) 
    {
        int m = grid.size(), n = grid[0].size();
        vector<vector<bool>> visited(m, vector<bool>(n));
        queue<pair<int, int>> q;

        // 1. 把边上的 1 加入到队列中
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                if (i == 0 || i == m - 1 || j == 0 || j == n - 1)
                    if (grid[i][j] == 1) 
                    {
                        q.push({i, j});
                        visited[i][j] = true;
                    }

        // 2. 多源 BFS
        while (!q.empty()) 
        {
            auto [a, b] = q.front();
            q.pop();
            for (int i = 0; i < 4; i++) 
            {
                int x = a + dx[i], y = b + dy[i];
                if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] == 1 && !visited[x][y]) 
                {
                    visited[x][y] = true;
                    q.push({x, y});
                }
            }
        }

        // 3. 统计结果
        int ret = 0;
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                // 统计未被包围的陆地单元格数量
                if (grid[i][j] == 1 && !visited[i][j])
                    ret++;
        return ret;
    }
};

地图中的最高点

题目:地图中的最高点

在这里插入图片描述
思路

  • 读完题后,本题思路和01矩阵基本一样;
  • 要想使最高高度值最大,我们从0位置向外拓展一层,将为访问的区域+1,循环,直至矩阵中全部都被遍历;

C++代码

class Solution 
{
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
public:
    vector<vector<int>> highestPeak(vector<vector<int>>& isWater) 
    {
        int m = isWater.size(), n = isWater[0].size();
        vector<vector<int>> dist(m, vector<int>(n, -1));
        queue<pair<int, int>> q;

        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(isWater[i][j] == 1)
                {
                    q.push({i, j});
                    dist[i][j] = 0;
                }

        while(!q.empty())
        {
            auto [a, b] = q.front(); q.pop();
            for(int i = 0; i < 4; i++)
            {
                int x = a + dx[i], y = b + dy[i];
                if(0 <= x && x < m && 0 <= y && y < n && dist[x][y] == -1)
                {
                    dist[x][y] = dist[a][b] + 1;
                    q.push({x, y});
                }
            }
        }

        return dist;
    }
};

地图分析

题目:地图分析

在这里插入图片描述
思路

海洋到陆地的最大<==>陆地到海洋的最大
和上面代码基本一样,只需修改最终结果

C++代码

class Solution 
{
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
public:
    int maxDistance(vector<vector<int>>& grid) 
    {
        int m = grid.size(), n = grid[0].size();
        vector<vector<int>> dist(m, vector<int>(n, -1));
        queue<pair<int, int>> q;

        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(grid[i][j])
                {
                    q.push({i, j});
                    dist[i][j] = 0;
                }

        int ret = -1;
        while(!q.empty())
        {
            auto [a, b] = q.front(); q.pop();
            for(int i = 0; i < 4; i++)
            {
                int x = a + dx[i], y = b + dy[i];
                if(0 <= x && x < m && 0 <= y && y < n && dist[x][y] == -1)
                {
                    dist[x][y] = dist[a][b] + 1;
                    q.push({x, y});
                    ret = max(ret, dist[x][y]);
                }
            }
        }
        return ret;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2198597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0基础跟德姆(dom)一起学AI 机器学习04-逻辑回归

逻辑回归简介 应用场景 逻辑回归是解决二分类问题的利器 数学知识 sigmoid函数 概率 极大似然估计 核心思想&#xff1a; 设模型中含有待估参数w&#xff0c;可以取很多值。已经知道了样本观测值&#xff0c;从w的一切可能值中&#xff08;选出一个使该观察值出现的概率为…

C++拾趣——绘制Console中DropdownMenu

大纲 居中显示窗口清屏并重设光标绘制窗口绘制窗口顶部绘制下拉行绘制下拉框选项绘制按钮行绘制窗口底部 修改终端默认行为对方向键的特殊处理过程控制Tab键的处理Enter键的处理上下左右方向键的处理 完整代码代码地址 这次我们要绘制下拉菜单&#xff0c;如下图。 居中显示窗口…

C语言 | Leetcode C语言题解之第466题统计重复个数

题目&#xff1a; 题解&#xff1a; #include <stdlib.h> #include <stdio.h> #include <stdbool.h> #include <string.h> #include <math.h> #include <limits.h>#define MMAX(a, b) ((a) > (b)? (a) : (b)) #define MMIN(a,…

xianshan分支预测器BPU

xianshan分支预测器BPU 1 RISC-V分支预测1.0 分支预测基本类型1.0.1 条件分支指令1.0.2 无条件分支指令 1.1 方向预测1.1.1 饱和计数器法1.1.1.1 Questions 1.1.2 分支历史法--程序局部性原理1.1.2.1 Questions 1.2 目标地址预测1.2.1 分支目标缓存--BTB 1.3 预测指令类型1.3.1…

【小白向】机器人入门之ROS系统的学习(Ubuntu24.04+ROS2)

目录 一.复杂的机器人系统 二.ROS机器人系统 1.简介 1.节点 2.话题 2.安装 3.测试 4.可视化 RQT&#xff1a; RVIZ&#xff1a; 显示属性&#xff1a; 显示状态&#xff1a; 一.复杂的机器人系统 依照我们现在的技术来看&#xff0c;机器人系统仍是极其复杂的&#xff0c;往…

深入了解音频剪辑在线工具的特色与优势

在数字时代&#xff0c;音频内容已成为连接人心的重要桥梁。如果你也有同样的兴趣爱好&#xff0c;那不妨看看我今天要介绍的音频剪辑在线相关的工具们吧。 1.福昕音频剪辑 链接直达>>https://www.foxitsoftware.cn/audio-clip/ 福昕音频剪辑工具&#xff0c;专为音乐…

【H2O2|全栈】关于CSS(11)flex——更加优雅的布局

目录 CSS3入门 前言 准备工作 布局优化 如何使用flex布局 容器与成员 概念 轴线 容器的属性 成员的属性 预告和回顾 后话 CSS3入门 前言 本系列博客主要介绍CSS有关知识点&#xff0c;当前章节讲述CSS3相关内容。 本章节讲述flex布局的相关知识。 部分内容仅代…

数据结构 ——— 单链表oj题:环形链表

目录 题目要求 手搓简易环状单链表 代码实现 问题1&#xff1a;slow 指针和 fast 指针一定会相遇吗 问题2&#xff1a;slow 每次走一步&#xff0c;fast 每次走 n 步是否还能判断链表带环&#xff1f;&#xff08;n > 2&#xff09; 题目要求 有一个单链表的头节点 …

【翻译】在 Python 应用程序中使用Qt Designer的UI文件

原文地址&#xff1a;Using a Designer UI File in Your Qt for Python Application 直接上图&#xff0c;上代码 将UI文件转为Python To demonstrate, we use the Qt Widgets animation easing example. 为了演示&#xff0c;我们使用 Qt Widgets 动画简化示例。 这个应用程…

快递查询软件:实现单号识别与批量物流查询的高效工具

随着网络购物的普及&#xff0c;快递物流行业迎来了前所未有的发展机遇&#xff0c;同时也面临着巨大的挑战。跟踪物流信息成为一个难题&#xff0c;因此&#xff0c;快递查询软件的核心功能之一便是单号识别。传统的快递单号输入方式繁琐且易出错在此背景下&#xff0c;快递查…

游戏盒子推广全攻略:从用户洞察到策略实施

在移动互联网时代&#xff0c;游戏盒子的推广已经成为众多游戏代理商和开发者的重要课题。面对激烈的市场竞争&#xff0c;如何高效吸引并留住玩家&#xff0c;成为游戏盒子推广的关键。本文将结合Xinstall这一专业App推广工具&#xff0c;探讨游戏盒子推广的有效策略。 一、市…

详细分析Java8中的StringJoiner | 对比StringBuilder(附Demo)

目录 前言1. 差异对比2. 基本知识3. 源码分析4. Demo 前言 对于Java的基本知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;【Java项目】实战CRUD的功能整理&#xff08;持续更新&#xff09; 1. 差异对比 展…

多种方式确定Linux是CentOS还是Ubuntu

目录 前言正文 前言 对应的基本知识比较少&#xff0c;以下只是记录总结 由于目前使用的是centos&#xff0c;后续找到linux会对应补充 正文 要确定Linux系统是CentOS还是Ubuntu&#xff0c;可以通过以下几种方式进行分析 一、查看发行版信息文件&#xff1a; CentOS&…

UE5运行时动态加载场景角色动画任意搭配-角色及动画(一)

通过《MMD模型及动作一键完美导入UE5》系列文章,我们可以把外部场景、角色、动画资产导入UE5,接下来我们将实现运行时动态加载这些资产,并任意组合搭配。 1、骨骼动画复用 1、大部分模型骨骼是不通用的,比如这些裙子也是有骨骼的,属于模型特有的,但是对于动画来说,很多…

【实时计算 Flink】SQL作业大状态导致反压的调优原理与方法

状态管理不仅影响应用的性能&#xff0c;还关系到系统的稳定性和资源的有效利用。如果状态管理不当&#xff0c;可能会导致性能下降、资源耗尽&#xff0c;甚至系统崩溃。本文为您介绍SQL作业大状态导致反压的调优原理与方法。 运行原理&#xff1a;状态算子的产生 作为一种特…

面试题:Redis(二)

1. 面试题 2. MoreKey案列 事故案例 2.1 生成上如何限制key*/flushdb/flushall等危险命令的使用&#xff1f; 通过redis.conf配置文件中在SECURITY选项中禁用这些命令 2.2 不用key*避免卡顿那用什么&#xff1f; 用scan命令&#xff0c;类似mysql中的limit命令 语法&…

数学建模算法与应用 第2章 整数规划及其求解方法

目录 2.1 概述 2.2 0-1整数规划模型 2.3 分枝定界法&#xff08;Branch and Bound&#xff09; 2.4 蒙特卡洛法&#xff08;随机取样法&#xff09; Matlab代码示例&#xff1a;蒙特卡洛法求解简单整数规划 2.5 整数规划的计算机求解工具 习题 2 总结 整数规划是线性规…

Window11 安装Java21教程

随着Java版本的迭代&#xff0c;最新的长期支持版本已经更新到Java21了&#xff0c;虽然笔者许多代码还是当年用Java8写的&#xff0c;但抱残守缺从来不适合IT人员&#xff0c;该来的我们始终要欣然面对。 其实随着各项技术的发展&#xff0c;Java许多组件现在其实都不需要或者…

Authentication Lab | Client Side Auth

关注这个靶场的其它相关笔记&#xff1a;Authentication Lab —— 靶场笔记合集-CSDN博客 0x01&#xff1a;Client Side Auth 前情提要 有些时候&#xff0c;开发人员会将身份验证的逻辑写于前端&#xff0c;这样写是十分不安全的&#xff0c;因为前端的代码几乎全部都是可见的…

借助微软 Teams 中的 Tableau,加速数据驱动型决策与协作流程

Tableau 应用已正式上线 Teams 商店&#xff01;如此&#xff0c;企业就能以一种更可靠和安全的方式在 Teams 中共享数据见解。 让团队能快速协作做出数据驱动型决策不再是可选项&#xff0c;而是业务成功的必备条件。 在几个月前的TC24 大会上&#xff0c;Tableau 再次表明了…