算法笔记(十四)——多源 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;
    }
};
相关推荐
三玖诶1 分钟前
C/C++解析文件名和目录路径
c语言·开发语言·c++
沐泽Mu10 分钟前
嵌入式学习-线性表-Day04-队列
c语言·开发语言·算法
2401_8572979112 分钟前
招联金融2025秋招倒计时
java·前端·算法·金融·求职招聘
微刻时光12 分钟前
Docker镜像命令汇总笔记
linux·运维·笔记·ubuntu·docker·容器·centos
侯孟禹17 分钟前
ubutun安装ffmpeg
笔记·ffmpeg
侯孟禹21 分钟前
RTSP推流服务搭建
笔记
Xerale24 分钟前
Laravel Admin 中的 “Array to String Conversion“ 问题及其解决方法
前端·数据库·笔记·php·laravel
zaiyang遇见33 分钟前
【第2章 开始学习C++】C++语句
开发语言·算法·c++11·c/c++·信息学奥赛·c++primer+plus
ArmeriaLeap36 分钟前
P9751 [CSP-J 2023] 旅游巴士
c++·算法·图论
桃酥40341 分钟前
图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)
c++·深度优先·图论·广度优先·卡码网