[Algorithm][多源BFS][矩阵][飞地的数量][地图中的最高点][地图分析] + 多源BFS原理讲解 详细讲解

news2024/11/25 16:52:05

目录

  • 0.原理讲解
  • 1.矩阵
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 2.飞地的数量
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 3.地图中的最高点
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现
  • 4.地图分析
    • 1.题目链接
    • 2.算法原理详解
    • 3.代码实现


0.原理讲解

  • 注意:只要是用**BFS解决的最短路径问题,都要求边权为一(边权值相同)**

  • 单源最短路径

    • 把起点加入到队列中
    • 一层一层的往外扩展
  • 多源BFS:用BFS解决边权为一多源最短路径问题
    请添加图片描述

  • 法一:暴力解,把多源最短路径问题转化为若干个单源最短路问题

    • 效率低,大概率会超时
  • 法二:把所有的源点当成一个"超级源点"

    • 此时问题就变成了「单源最短路径」问题
      请添加图片描述
  • "超级源点"的正确性?感性理解

    • 同时从几个源点出发,会存在"舍弃"几个"不好的点"的现象
    • 远的源点走一步肯定没有近的源点走一步好,所以相当于舍去了远的源点
  • 多源BFS如何代码实现?

    • 所有的源点加入到队列里面
    • 一层一层的往外扩展
      请添加图片描述

1.矩阵

1.题目链接

  • 矩阵

2.算法原理详解

  • 思路一:一个位置一个位置求

    • 不用想,这么暴力肯定超时:P
  • 思路二多源BFS + 正难则反 -> 把所有的0当成起点,1当成终点

    • 把所有的0位置加入到队列中
    • 一层一层的向外拓展即可
      请添加图片描述
  • 为什么正着做会很困难呢?

    • 正着做虽然能找到0,但是想把距离存下来,会很难
    • 并且也无法知道是哪个1到了0,距离是多少
  • 为什么本题用到了多源BFS呢?

    • 0是有很多个的,怎么才能保证遇到的1距离这⼀个0是最近的?
    • 先把所有的0都放在队列中,把它们当成⼀个整体,每次把当前队列⾥⾯的所有元素向外扩展⼀次
  • 细节:在单源最短路径中需要:bool visit[i][j]stepsz,而在多源BFS中,只需要一个int dist[i][j]就可以替代这三者的功能

    • 为什么可以替代bool visit[i][j]
      • dist[][]初始化为-1-1表示没有搜索过
      • dist[i][j] != -1则为最短距离
    • <为什么可以替代step
      • (a, b) -> (x, y)dist[a][b]存储了dist[x][y]上一步的距离
        • dist[x][y] = dist[a][b] + 1
    • 为什么可以替代sz
      • 因为不强制一定要按层一层一层出队列,可以一个元素一个元素的往外扩展
      • 不需要知道此时是哪一层,dist[i][j]已经标记了现在是属于哪一层

3.代码实现

vector<vector<int>> UpdateMatrix(vector<vector<int>>& mat) 
{
    int n = mat.size(), m = mat[0].size();

    // dist[i][j] == -1 未搜索过
    // dist[i][j] != -1 最短距离
    vector<vector<int>> dist(n, vector<int>(m, -1));
    queue<pair<int, int>> q;

    // 将所有源点加入到队列中
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(mat[i][j] == 0)
            {
                q.push({i, j});
                dist[i][j] = 0;
            }
        }
    }

    // 多源BFS
    while(q.size())
    {
        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 < n && y >= 0 && y < m && dist[x][y] == -1)
            {
                dist[x][y] = dist[a][b] + 1;
                q.push({x, y});
            }
        }
    }

    return dist;
}

2.飞地的数量

1.题目链接

  • 飞地的数量

2.算法原理详解

  • 思路一:一个一个去判断
    • 不用想,这么暴力肯定超时:P
  • 思路二多源BFS + 正难则反 -> 从边界上的1开始,做一次搜索
    • 多源BFS结束后,重新遍历一次数组,最后剩下来的就都是飞地
      请添加图片描述

3.代码实现

int NumEnclaves(vector<vector<int>>& grid) 
{
    int n = grid.size(), m = grid[0].size();
    vector<vector<bool>> visit(n, vector<bool>(m, false));
    queue<pair<int, int>> q;

    // 将所有边界1入队列
    for(int i = 0; i < n; i++)
    {
        if(grid[i][0] == 1)
        {
            q.push({i, 0});
            visit[i][0] = true;
        }

        if(grid[i][m - 1] == 1)
        {
            q.push({i, m - 1});
            visit[i][m - 1] = true;
        }
    }

    for(int i = 0; i < m; i++)
    {
        if(grid[0][i] == 1)
        {
            q.push({0, i});
            visit[0][i] = true;
        }

        if(grid[n - 1][i] == 1)
        {
            q.push({n - 1, i});
            visit[n - 1][i] = true;
        }
    }

    // 多源BFS
    while(q.size())
    {
        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 < n && y >= 0 && y < m \
               && grid[x][y] == 1 && !visit[x][y])
            {
                visit[x][y] = true;
                q.push({x, y});
            }
        }
    }

    // 遍历计数
    int count = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(grid[i][j] == 1 && !visit[i][j])
            {
                count++;
            }
        }
    }

    return count;
}

3.地图中的最高点

1.题目链接

  • 地图中的最高点

2.算法原理详解

  • "01矩阵"变形题,直接多源BFS即可

3.代码实现

class Solution 
{
    int dx[4] = {1, -1, 0, 0};
    int dy[4] = {0, 0, 1, -1};
public:
    vector<vector<int>> highestPeak(vector<vector<int>>& isWater) 
    {
        int n = isWater.size(), m = isWater[0].size();
        vector<vector<int>> dist(n, vector<int>(m, -1));
        queue<pair<int, int>> q;
        
        // 将边界水域入队列
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                if(isWater[i][j])
                {
                    dist[i][j] = 0;
                    q.push({i, j});
                }
            }
        }

        // 多源BFS
        while(q.size())
        {
            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 < n && y >= 0 && y < m && dist[x][y] == -1)
                {
                    dist[x][y] = dist[a][b] + 1;
                    q.push({x, y});
                }
            }
        }

        return dist;
    }
};

4.地图分析

1.题目链接

  • 地图分析

2.算法原理详解

  • "01矩阵"变形题,直接多源BFS即可

3.代码实现

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

        // 将陆地入队列
        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < n; j++)
            {
                if(grid[i][j])
                {
                    dist[i][j] = 0;
                    q.push({i, j});
                }
            }
        }

        // 多源BFS
        int ret = -1;
        while(q.size())
        {
            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 < n && y >= 0 && 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/1651269.html

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

相关文章

淘宝数据分析——Python爬虫模式♥

大数据时代&#xff0c; 数据收集不仅是科学研究的基石&#xff0c; 更是企业决策的关键。 然而&#xff0c;如何高效地收集数据 成了摆在我们面前的一项重要任务。 本文将为你揭示&#xff0c; 一系列实时数据采集方法&#xff0c; 助你在信息洪流中&#xff0c; 找到…

每日OJ题_贪心算法三③_力扣45. 跳跃游戏 II(dp解法+贪心解法)

目录 力扣45. 跳跃游戏 II 解析代码1_动态规划 解析代码2_贪心 力扣45. 跳跃游戏 II 45. 跳跃游戏 II 难度 中等 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 num…

如何设置ddns动态域名服务实现外网访问

在本地搭建好服务器&#xff0c;部署好web网站或其他应用后&#xff0c;需要在外网访问内网时&#xff0c;如何设置动态域名服务ddns&#xff0c;将主机的内网IP端口映射到外网访问&#xff0c;是我们需要面对的一个重要步骤。 内网发布外网&#xff0c;常见的有两种方案&…

C语言程序设计(三)

1、数据的两种表现形式 常量&#xff1a;其值不能被改变的量称为常量。 变量&#xff1a; 单撇号内只能包含一个字符。双撇号内可以包含一个字符串。 注意&#xff1a;要区分符号常量和变量,不要把符号常量误认为变量。符号常量不占内存只是一个临时符号,代表一个值,在预编译…

QT和Halcon联合编程--注意是Ubuntu--

1.在QT目录下面的.pro文件下&#xff0c;如图所示&#xff1a; 根据你电脑的haclon的安装路径&#xff0c;添加如下代码&#xff1a; INCLUDEPATH /opt/halcon/include LIBS -L/opt/halcon/lib/x64-linux -lhalconcpp 需要等待一下&#xff0c;QT需要进行加载 2.在头文件中…

【综述】碳达峰、碳中和、碳足迹

文章目录 概念定义 碳足迹计算 动力蓄电池碳足迹 服务应用 参考资料 概念定义 温室气体&#xff0c;大气层中自然存在的和由于人类活动产生的能够吸收和散发由地球表面、大气层和云层所产生的、波长在红外光谱内的辐射的气态成分。包括二氧化碳&#xff08;CO2&#xff09…

HIVE简单数据查询

HIVE简单数据查询 1.where WHERE 过滤条件 between/ in / is NULL / IS NOT NULL / > < ! ... 如果多个存在多个过滤条件 可以用 AND OR 进行条件关联 或者是用NOT 进行条件结果取反 2.JOIN JOIN 内连接 左外连接 右外连接 自连接 满连接…

Unity 性能优化之LOD技术(十)

提示&#xff1a;仅供参考&#xff0c;有误之处&#xff0c;麻烦大佬指出&#xff0c;不胜感激&#xff01; 文章目录 LOD技术效果一、LOD技术是什么&#xff1f;二、LODGroup组件介绍三、LODGroup组件使用步骤添加组件添加模型 四、Project Settings中与LOD组件相关参数总结 L…

视觉图像信息处理与FPGA实现第九次作业——直方图均衡

RAM的B站视频解析 RAM的文档 一、65536x8位的单端口RAM timescale 1ns / 1ps //SPRF Single Port Read/Write Function //65535 是RAM中总的字数&#xff0c;也就是存储深度&#xff0c;X8表示每个字是8位的 module SPRF65536X8(Q,CLK,CEN,WEN,A,D );//输出寄存器Qoutput [7…

k8s集群统一设置时间

1 安装时间同步需要软件 yum install -y ntpdate2 设置时间 2.1 手动设置时间 date -s "20190712 18:30:50" hwclock --systohc2.2 在线更新时间 ntpdate 0.asia.pool.ntp.org # 强制把系统时间写入CMOS clock -w3 强制把系统时间写入CMOS hwclock作用与clock相…

N7552A是德科技N7552A电子校准件

181/2461/8938产品概述&#xff1a; 更小巧轻便的 2 端口模块&#xff0c;支持 3.5 mm 或 N 型 50 Ω 连接器&#xff0c;能够将校准时间缩短一半 特点 频率范围&#xff1a;直流至 9 GHz 使用 N 型或 3.5 mm 连接器 更小巧轻便的 2 端口电子校准件&#xff08;ECal&#xff…

电脑(爱好者) :基础知识1 了解你的电脑

读懂cpu 您想了解关于您的电脑的信息吗&#xff1f;CPuz是一款常用的系统信息工具&#xff0c;可以提供关于CPU、主板、内存等硬件信息的详细情况。您可以下载并运行该软件&#xff0c;然后查看您的电脑硬件配置信息。 图片来源于网络 CPU-Z 简介 CPU-Z 是一款功能强大且易于使…

迅为RK3568开发板资料说明4750+页专属文档专为3568编写

iTOP-3568开发板采用瑞芯微RK3568处理器&#xff0c;内部集成了四核64位Cortex-A55处理器。主频高达2.0Ghz&#xff0c;RK809动态调频。集成了双核心架构GPU&#xff0c;ARM G52 2EE、支持OpenGLES1.1/2.0/3.2、OpenCL2.0、Vulkan1.1、内嵌高性能2D加速硬件。 内置独立NPU,算力…

绝地求生:新型小队对决系统或将择日上线?

就在刚才&#xff0c;PUBG官博发布了一则短视频&#xff0c;视频内容为两只小队通过竞争积分排名产生不断地变化。 原文官博 视频内容 在这里我猜测为之前官方在2024工作计划视频中介绍过的新型小队对决系统&#xff1a; 据当时的介绍称&#xff1a;这个系统中&#xff0c;己方…

大数据基础工程技术团队4篇论文入选ICLR,ICDE,WWW

近日&#xff0c;由阿里云计算平台大数据基础工程技术团队主导的四篇时间序列相关论文分别被国际顶会ICLR2024、ICDE2024和WWW2024接收。 论文成果是阿里云与华东师范大学、浙江大学、南京大学等高校共同研发&#xff0c;涉及时间序列与智能运维结合的多个应用场景。包括基于P…

2024DCIC海上风电出力预测Top方案 + 光伏发电出力高分方案学习记录

海上风电出力预测 赛题数据 海上风电出力预测的用电数据分为训练组和测试组两大类&#xff0c;主要包括风电场基本信息、气象变量数据和实际功率数据三个部分。风电场基本信息主要是各风电场的装机容量等信息&#xff1b;气象变量数据是从2022年1月到2024年1月份&#xff0c;…

大数据Scala教程从入门到精通第三篇:Scala和Java的关系

一&#xff1a;Scala和Java的关系 1&#xff1a;详解 一般来说&#xff0c;学 Scala的人&#xff0c;都会 Java&#xff0c;而 Scala 是基于 Java 的&#xff0c;因此我们需要将 Scala和 Java 以及 JVM 之间的关系搞清楚&#xff0c;否则学习 Scala 你会蒙圈 Scala可以使用SDK…

力扣70 爬楼梯 C语言 动态规划 递归

题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到楼顶。 1. 1 阶 1 阶 2. 2 阶 示例 2…

leetCode75. 颜色分类

leetCode75. 颜色分类 题目思路 代码 class Solution { public:void sortColors(vector<int>& nums) {for(int i 0, j 0, k nums.size() - 1; i < k;){if(nums[i] 0) swap(nums[i],nums[j]);else if(nums[i] 2) swap(nums[i],nums[k--]);else if(nums[i] …

前端数据可视化基础(折线图)

目录 前言&#xff1a; 画布&#xff1a; 折线图 (Line Chart): 前言&#xff1a; 前端中的数据可视化是指将大量数据以图形或图像的形式在前端页面上展示出来&#xff0c;以便用户能够更直观地理解和分析这些数据。数据可视化是一种强大的工具&#xff0c;它利用了人类视觉…