多源bfs方法可以解决leetcode 上的一类题,
一般来说我们使用BFS都是单源的,如二叉树层次遍历等leetcode 上的很多题目,我们起始阶段只需要将某一个元素加入队列。
多源顾名思义就是开始阶段加入多个元素入队列,我们也可以将其理解为存在一个超级源点。
如下994题腐败的橘子,网格中存在若干个腐败橘子,我们需要求出所有新鲜橘子被腐烂的时间。如果按单源的bfs,从一个腐烂橘子开始遍历,那么每个新鲜橘子可能存在多个时间点,我们需要取最小,这非常复杂。
如
2,0,0
1,1,0
0,2,0
单源BFS:
从(0,0)开始得出(1,0)为1分钟,(1,1)为2分钟
从(2,1)开始得出(1,0)为2分钟,(1,1)为1分钟
多源BFS:
(0,0),(2,1)全部加入队列,以一种扩散的思想就能够一步到位得到结果。
,leetcode 994
class Solution {
const int path[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
public:
int orangesRotting(vector<vector<int>>& grid) {
queue<pair<int,int>>q;
auto m=grid.size(), n=grid[0].size();
vector<vector<int>>vis(m,vector<int>(n));
int time=0,cnt=0;
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if(grid[i][j]==2)
{
q.emplace(i,j);
vis[i][j]=1;
}
if(grid[i][j]==1)++cnt;
}
}
if(cnt==0)return 0;
while(!q.empty())
{
auto sz=q.size();
while(sz)
{
auto [x,y]=q.front();
--sz;
q.pop();
for(int d=0;d<=3;++d)
{
int i=x+path[d][0];
int j=y+path[d][1];
if(i>=0&&i<m&&j>=0&&j<n&&grid[i][j]&&vis[i][j]==0)
{
q.emplace(i,j);
--cnt;
vis[i][j]=1;
}
}
}
time++;
}
return cnt==0?time-1:-1;
}
};
class Solution {
static constexpr int path[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
queue<pair<int,int>>q;
auto m=matrix.size(),n=matrix[0].size();
vector<vector<int>>dis(m,vector<int>(n));
vector<vector<int>>vis(m,vector<int>(n));
for(int i=0;i<m;++i)
{
for(int j=0;j<n;++j)
{
if(matrix[i][j]==0)
{
q.push({i,j});
dis[i][j]=0;
vis[i][j]=1;
}
}
}
while(!q.empty())
{
auto [x,y]=q.front();
q.pop();
for(int d=0;d<4;++d)
{
int i=x+path[d][0];
int j=path[d][1]+y;
if(i>=0&&i<m&&j>=0&&j<n&&vis[i][j]==0)
{
dis[i][j]=dis[x][y]+1;
vis[i][j]=1;
q.push({i,j});
}
}
}
return dis;
}
};
class Solution {
public:
static constexpr int MAX_N = 100 + 5;
static constexpr int INF = int(1E6);
static constexpr int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
int n;
int d[MAX_N][MAX_N];
struct Coordinate {
int x, y;
};
queue <Coordinate> q;
int maxDistance(vector<vector<int>>& grid) {
this->n = grid.size();
auto &a = grid;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
d[i][j] = INF;
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (a[i][j]) {
d[i][j] = 0;
q.push({i, j});
}
}
}
while (!q.empty()) {
auto f = q.front(); q.pop();
for (int i = 0; i < 4; ++i) {
int nx = f.x + dx[i], ny = f.y + dy[i];
if (!(nx >= 0 && nx <= n - 1 && ny >= 0 && ny <= n - 1)) continue;
if (d[nx][ny] > d[f.x][f.y] + 1) {
d[nx][ny] = d[f.x][f.y] + 1;
q.push({nx, ny});
}
}
}
int ans = -1;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (!a[i][j]) ans = max(ans, d[i][j]);
}
}
return (ans == INF) ? -1 : ans;
}
};