算法笔记(十四)——多源 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;
    }
};
相关推荐
真的想上岸啊15 分钟前
学习C++、QT---21(QT中QFile库的QFile读取文件、写入文件的讲解)
c++·qt·学习
小庞在加油38 分钟前
Apollo源码架构解析---附C++代码设计示例
开发语言·c++·架构·自动驾驶·apollo
体系结构论文研讨会43 分钟前
多项式环及Rq的含义
算法
智驱力人工智能1 小时前
极端高温下的智慧出行:危险检测与救援
人工智能·算法·安全·行为识别·智能巡航·高温预警·高温监测
森焱森1 小时前
60 美元玩转 Li-Fi —— 开源 OpenVLC 平台入门(附 BeagleBone Black 驱动简单解析)
c语言·单片机·算法·架构·开源
我喜欢就喜欢1 小时前
RapidFuzz-CPP:高效字符串相似度计算的C++利器
开发语言·c++
千帐灯无此声1 小时前
Linux 测开:日志分析 + 定位 Bug
linux·c语言·c++·bug
莫彩1 小时前
【Modern C++ Part7】_创建对象时使用()和{}的区别
开发语言·c++
课堂剪切板2 小时前
ch07 题解
算法·深度优先
潇-xiao2 小时前
进程状态 + 进程优先级切换调度-进程概念(5)
linux·笔记