文章目录
多源 BFS
单源最短路问题:一个起点到一个终点的最短路;
解决步骤:
- 把起点放进队列里
- 一层一层往外扩
相关文章: 算法笔记(十三)------BFS 解决最短路问题
多源最短路问题:多个起点到同一个终点的最短路;
多源BFS :用BFS
来解决多源最短路问题
如何解决???
- 把所有源点当成一个源点
<==>
单一的最短路问题解决步骤
- 把所有起点放进队列里
- 一层一层往外扩
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;
}
};