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

文章目录

多源 BFS

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

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

相关文章: 算法笔记(十三)------BFS 解决最短路问题
多源最短路问题:多个起点到同一个终点的最短路;
多源BFSBFS来解决多源最短路问题
如何解决???

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

解决步骤

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

01 矩阵

题目:01 矩阵


思路

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

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

C++代码

cpp 复制代码
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)

cpp 复制代码
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)

cpp 复制代码
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++代码

cpp 复制代码
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++代码

cpp 复制代码
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;
    }
};
相关推荐
go_bai7 分钟前
Linux环境基础开发工具——(2)vim
linux·开发语言·经验分享·笔记·vim·学习方法
Zhichao_9714 分钟前
【UE5 C++课程系列笔记】33——商业化Json读写
c++·ue5
吴梓穆16 分钟前
UE5学习笔记 FPS游戏制作35 使用.csv配置文件
笔记·学习·ue5
惊鸿.Jh16 分钟前
【滑动窗口】3254. 长度为 K 的子数组的能量值 I
数据结构·算法·leetcode
明灯L16 分钟前
《函数基础与内存机制深度剖析:从 return 语句到各类经典编程题详解》
经验分享·python·算法·链表·经典例题
100分题库小程序22 分钟前
2025年机动车授权签字人考试判断题分享
经验分享·笔记
碳基学AI22 分钟前
哈尔滨工业大学DeepSeek公开课:探索大模型原理、技术与应用从GPT到DeepSeek|附视频与讲义免费下载方法
大数据·人工智能·python·gpt·算法·语言模型·集成学习
补三补四25 分钟前
机器学习-聚类分析算法
人工智能·深度学习·算法·机器学习
V---scwantop---信34 分钟前
失真扭曲斑点效果ps标题文本特效滤镜样机 Color Blob Distort Text & Logo Effect
笔记
独好紫罗兰36 分钟前
洛谷题单3-P5718 【深基4.例2】找最小值-python-流程图重构
开发语言·python·算法