图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)

图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网))

    • 广度优先搜索理论基础
      • bfs与dfs的对比(思维导图):
    • 99.岛屿数量(卡码网)
      • 1.深搜法
      • 2.广搜法
    • 100.岛屿的最大面积(卡码网)

广度优先搜索理论基础

  • 应用场景:

    • 适合于解决两个点之间的最短路径问题
    • 不涉及具体的遍历方式,深搜和广搜都可以
  • 广搜(bfs)的过程:

    图二

  • 代码框架:

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1}; // 表示四个方向
// grid 是地图,也就是一个二维数组
// visited标记访问过的节点,不要重复访问
// x,y 表示开始搜索节点的下标
void bfs(vector<vector<char>>& grid, vector<vector<bool>>& visited, int x, int y) {
    queue<pair<int, int>> que; // 定义队列
    que.push({x, y}); // 起始节点加入队列
    visited[x][y] = true; // 只要加入队列,立刻标记为访问过的节点
    while(!que.empty()) { // 开始遍历队列里的元素
        pair<int ,int> cur = que.front(); que.pop(); // 从队列取元素
        int curx = cur.first;
        int cury = cur.second; // 当前节点坐标
        for (int i = 0; i < 4; i++) { // 开始想当前节点的四个方向左右上下去遍历
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1]; // 获取周边四个方向的坐标
            if (nextx < 0 || nextx >= grid.size() || nexty < 0 || nexty >= grid[0].size()) continue;  // 坐标越界了,直接跳过
            if (!visited[nextx][nexty]) { // 如果节点没被访问过
                que.push({nextx, nexty});  // 队列添加该节点为下一轮要遍历的节点
                visited[nextx][nexty] = true; // 只要加入队列立刻标记,避免重复访问
            }
        }
    }

}

要素:

  • 表示方向的二维数组
  • 表示地图的二维数组
  • 表示是否访问的二维数组
  • 坐标的数据类型
  • 能存储坐标的队列
  • 当前结点(curx,cury)和下一个结点坐标(nextx,nexty)

代码思路:将起始点存入队列并获取当前元素,再根据当前元素获取下一个元素,并存入队列

(以上主要摘自代码随想录)

bfs与dfs的对比(思维导图):

在这里插入图片描述

99.岛屿数量(卡码网)

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,你需要计算岛屿的数量。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。

后续 N 行,每行包含 M 个数字,数字为 1 或者 0。

输出描述

输出一个整数,表示岛屿的数量。如果不存在岛屿,则输出 0。

输入示例

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出示例

3

提示信息

img

根据测试案例中所展示,岛屿数量共有 3 个,所以输出 3。

数据范围:

1 <= N, M <= 50

1.深搜法

#include <iostream>
#include <vector>
using namespace std;

int dir[4][2]={0, 1, 1, 0, -1, 0, 0, -1};

void dfs(const vector<vector<int>> &grid,vector<vector<bool>> &visited,int x,int y)
{
    if(grid[x][y]==0||visited[x][y])
        return;
    visited[x][y]=true;
    for(int i=0;i<4;i++)
    {
        int nextx=x+dir[i][0];
        int nexty=y+dir[i][1];
        if(nextx<=0||nextx>=grid.size()||nexty<=0||nexty>=grid[1].size())
            continue;
        dfs(grid,visited,nextx,nexty);
    }
}

int main()
{
    int n,m;
    cin>>n>>m;
    vector<vector<int>> grid(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            cin>>grid[i][j];
        }
    vector<vector<bool>> visited(n+1,vector<bool>(m+1,false));
    int result=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(grid[i][j]==1&&!visited[i][j])
            {
                result++;
                dfs(grid,visited,i,j);
            }
    cout<<result<<endl;
    return 0;
}

2.广搜法

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int dir[4][2]={1,0,-1,0,0,1,0,-1};
void bfs(vector<vector<int>> grid,vector<vector<bool>>& visited,int x,int y)
{
    queue<pair<int,int>> que;
    que.push({x,y});
    visited[x][y]=true;
    while(!que.empty())
    {
        pair<int,int> cur=que.front();
        que.pop();
        int curx=cur.first;
        int cury=cur.second;
        for(int i=0;i<4;i++)
        {
            int nextx=curx+dir[i][0];
            int nexty=cury+dir[i][1];
            if(nextx<=0||nextx>=grid.size()||nexty<=0||nexty>=grid[1].size())
                continue;
            if(grid[nextx][nexty]==1&&visited[nextx][nexty]==false)
            {
                que.push({nextx,nexty});
                visited[nextx][nexty]=true;
            }
        }
    }
}

int main()
{
    int n,m;
    cin>>n>>m;
    vector<vector<int>> grid(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>grid[i][j];
    vector<vector<bool>> visited(n+1,vector<bool>(m+1,false));
    int result=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(visited[i][j]==false&&grid[i][j]==1)
            {
                result++;
                bfs(grid,visited,i,j);
            }
    cout<<result<<endl;
}

分析思路如下:

在这里插入图片描述

100.岛屿的最大面积(卡码网)

题目描述

给定一个由 1(陆地)和 0(水)组成的矩阵,计算岛屿的最大面积。岛屿面积的计算方式为组成岛屿的陆地的总数。岛屿由水平方向或垂直方向上相邻的陆地连接而成,并且四周都是水域。你可以假设矩阵外均被水包围。

输入描述

第一行包含两个整数 N, M,表示矩阵的行数和列数。后续 N 行,每行包含 M 个数字,数字为 1 或者 0,表示岛屿的单元格。

输出描述

输出一个整数,表示岛屿的最大面积。如果不存在岛屿,则输出 0。

输入示例

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

输出示例

4

提示信息

img

样例输入中,岛屿的最大面积为 4。

数据范围:

1 <= M, N <= 50。

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

int dir[4][2]={1,0,-1,0,0,1,0,-1};
void bfs(vector<vector<int>> grid,vector<vector<bool>> &visited,int x,int y,int &area)
{
    queue<pair<int,int>> que;
    que.push({x,y});
    visited[x][y]=true;
    area++;
    while(!que.empty())
    {
        pair<int,int> cur=que.front();
        que.pop();
        int curx=cur.first;
        int cury=cur.second;
        for(int i=0;i<4;i++)
        {
            int nextx=curx+dir[i][0];
            int nexty=cury+dir[i][1];
            if(nextx<=0||nextx>=grid.size()||nexty<=0||nexty>=grid[1].size())
                continue;
            if(grid[nextx][nexty]==1&&visited[nextx][nexty]==false)
            {
                que.push({nextx,nexty});
                visited[nextx][nexty]=true;
                area++;
            }
        }
    }
}

int main()
{
    int n,m;
    cin>>n>>m;
    vector<vector<int>> grid(n+1,vector<int>(m+1,0));
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>grid[i][j];
    vector<vector<bool>> visited(n+1,vector<bool>(m+1,false));
    int maxArea=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(visited[i][j]==false&&grid[i][j]==1)
            {
                int area=0;
                bfs(grid,visited,i,j,area);
                maxArea=max(maxArea,area);
            }
    cout<<maxArea<<endl;
}

在99题的基础上加一个area即可,基本没有难度

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

关于Linux下C++程序内存dump的分析和工具

前言 程序崩溃令人很崩溃&#xff0c;特别是让人找不到原因的崩溃&#xff0c;但是合适的工具可以帮助人很快的定位到问题&#xff0c;在AI基础能力ASR服务开发时&#xff0c;找到了一种比较实用和简单的内存崩溃的dump分析工具breakpad&#xff0c; 可以帮助在Linux下C开发程…

C语言初阶-数据类型和变量【下】

紧接上期------------------------->>>C语言初阶-数据类型和变量【上】 全局变量和局部变量在内存中存储在哪⾥呢&#xff1f; ⼀般我们在学习C/C语⾔的时候&#xff0c;我们会关注内存中的三个区域&#xff1a; 栈区 、 堆区 、 静态区 。 内存的分配情况 局部变量是…

Java->排序

目录 一、排序 1.概念 2.常见的排序算法 二、常见排序算法的实现 1.插入排序 1.1直接插入排序 1.2希尔排序(缩小增量法) 1.3直接插入排序和希尔排序的耗时比较 2.选择排序 2.1直接选择排序 2.2堆排序 2.3直接选择排序与堆排序的耗时比较 3.交换排序 3.1冒泡排序…

肺腺癌预后新指标:全切片图像中三级淋巴结构密度的自动化量化|文献精析·24-10-09

小罗碎碎念 本期这篇文章&#xff0c;我去年分享过一次。当时发表在知乎上&#xff0c;没有标记参考文献&#xff0c;配图的清晰度也不够&#xff0c;并且分析的还不透彻&#xff0c;所以趁着国庆假期重新分析一下。 这篇文章的标题为《Computerized tertiary lymphoid structu…

【实战】Nginx+Lua脚本+Redis 实现自动封禁访问频率过高IP

大家好&#xff0c;我是冰河~~ 自己搭建的网站刚上线&#xff0c;短信接口就被一直攻击&#xff0c;并且攻击者不停变换IP&#xff0c;导致阿里云短信平台上的短信被恶意刷取了几千条&#xff0c;加上最近工作比较忙&#xff0c;就直接在OpenResty上对短信接口做了一些限制&am…

《Linux运维总结:基于ARM64+X86_64架构CPU使用docker-compose一键离线部署mongodb 7.0.14容器版分片集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&…

C++入门基础知识110—【关于C++ if...else 语句】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C if...else 语句的相关内容&#xff01…

数据结构-5.2.树的性质

一.树的常考性质&#xff1a; 性质1&#xff1a;结点数 总度数 1(结点的度&#xff1a;结点分支的数量) 一个分支中&#xff0c;如父结点B&#xff0c;两个子结点为E和F&#xff0c;结点B的度的值为2&#xff0c;等于子结点数量&#xff0c;加上这一个父结点(父结点只能有一…

部署私有仓库以及docker web ui应用

官方地址&#xff1a;https://hub.docker.com/_/registry/tags 一、拉取registry私有仓库镜像 docker pull registry:latest 二、运⾏容器 docker run -itd -v /home/dockerdata/registry:/var/lib/registry --name "pri_registry1" --restartalways -p 5000:5000 …

数据结构-5.5.二叉树的存储结构

一.二叉树的顺序存储&#xff1a; a.完全二叉树&#xff1a; 1.顺序存储中利用了静态数组&#xff0c;空间大小有限&#xff1a; 2.基本操作&#xff1a; (i是结点编号) 1.上述图片中i所在的层次后面的公式应该把n换成i(图片里写错了)&#xff1b; 2.上述图片判断i是否有左…

ClickHouse的原理及使用,

1、前言 一款MPP查询分析型数据库——ClickHouse。它是一个开源的&#xff0c;面向列的分析数据库&#xff0c;由Yandex为OLAP和大数据用例创建。ClickHouse对实时查询处理的支持使其适用于需要亚秒级分析结果的应用程序。ClickHouse的查询语言是SQL的一种方言&#xff0c;它支…

网络安全之XXE攻击

0x01 什么是 XXE 个人认为&#xff0c;XXE 可以归结为一句话&#xff1a;构造恶意 DTD 介绍 XXE 之前&#xff0c;我先来说一下普通的 XML 注入&#xff0c;这个的利用面比较狭窄&#xff0c;如果有的话应该也是逻辑漏洞。 既然能插入 XML 代码&#xff0c;那我们肯定不能善罢…

图像分类-demo(Lenet),tensorflow和Alexnet

目录 demo(Lenet) 代码实现基本步骤&#xff1a; TensorFlow 一、核心概念 二、主要特点 三、简单实现 参数: 模型编译 模型训练 模型评估 Alexnet model.py train.py predict.py demo(Lenet) PyTorch提供了一个名为“torchvision”的附加库&#xff0c;其中包含…

【在Linux世界中追寻伟大的One Piece】信号捕捉|阻塞信号

目录 1 -> 信号捕捉初识 2 -> 阻塞信号 2.1 -> 信号其他相关常见概念 2.2 -> 在内核中的表示 2.3 -> sigset_t 2.4 -> 信号集操作函数 2.5 -> sigprocmask 2.6 -> sigpending 3 -> 捕捉信号 3.1 -> 内核如何实现信号的捕捉 3.2 ->…

VBA高级应用30例应用3Excel中的ListObject对象:选择表的一部分

《VBA高级应用30例》&#xff08;版权10178985&#xff09;&#xff0c;是我推出的第十套教程&#xff0c;教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开&#xff0c;这套教程案例与理论结合&#xff0c;紧贴“实战”&#xff0c;并做“战术总结”&#xff0c;以…

【Spring】获取 Cookie和Session

回顾 Cookie HTTP 协议自身是属于“无状态”协议 无状态&#xff1a;默认情况下&#xff0c;HTTP 协议的客户端和服务器之间的这次通信和下次通信之间没有直接的联系 但是在实际开发中&#xff0c;我们很多时候是需要知道请求之间的关联关系的 例如登录网站成功后&#xff…

Linux高效查日志命令介绍

说明&#xff1a;之前介绍Linux补充命令时&#xff0c;有介绍使用tail、grep命令查日志&#xff1b; Linux命令补充 今天发现仅凭这两条命令不够&#xff0c;本文扩展介绍一下。 命令一&#xff1a;查看日志开头 head -n 行数 日志路径如下&#xff0c;可以查看程序启动是否…

安装和配置k8s可视化UI界面dashboard-1.20.6

安装和配置k8s可视化UI界面dashboard-1.20.6 1.环境规划2.初始化服务器1&#xff09;配置主机名2&#xff09;设置IP为静态IP3&#xff09;关闭selinux4&#xff09;配置主机hosts文件5&#xff09;配置服务器之间免密登录6&#xff09;关闭交换分区swap&#xff0c;提升性能7&…

系统架构设计师考试背记精要

1、架构的本质&#xff1a; &#xff08;1&#xff09;软件架构为软件系统提供了一个结构、行为和属性的高级抽象。&#xff08;2&#xff09;软件架构风格是特定应用领域的惯用模式&#xff0c;架构定义一个词汇表和一组约束。 2、数据流风格&#xff1a;适合于分阶段做数据处…

Springboot从入门到起飞-【day01】

个人主页→VON 收录专栏→Springboot从入门到起飞 一、前言 经过了近两个月的沉淀开始了新专栏的学习&#xff0c;经过深思熟虑还是决定重新学习java&#xff0c;因为基础部分东西太多太乱就不进行逐一的更新了&#xff0c;等到学完了一同进行更新。 二、Springboot简要概述 …