Как работает мультиисточниковый BFS (от нескольких стартов сразу)?
Задача: на сетке несколько «пожаров», нужно для каждой клетки найти расстояние до ближайшего пожара. Запускать BFS из каждого источника отдельно — это O(источники × клетки), слишком медленно. Можно ли одним BFS?
2 ответа
Да — мультиисточниковый BFS. Кладём в очередь сразу все источники с расстоянием 0, дальше обычный BFS. Каждая клетка получит расстояние до ближайшего из них, потому что слои растут одновременно от всех стартов, и до клетки первым доберётся ближайший источник.
vector<vector<int>> dist(R, vector<int>(C, -1));
queue<pair<int,int>> q;
for (auto [r, c] : sources) { dist[r][c] = 0; q.push({r, c}); }
while (!q.empty()) {
auto [r, c] = q.front(); q.pop();
for (auto [dr, dc] : {pair{0,1},{0,-1},{1,0},{-1,0}}) {
int nr = r + dr, nc = c + dc;
if (nr>=0 && nr<R && nc>=0 && nc<C && dist[nr][nc]==-1) {
dist[nr][nc] = dist[r][c] + 1;
q.push({nr, nc});
}
}
}
Сложность O(V + E) независимо от числа источников (на сетке O(R·C)). Это правильный приём вместо k отдельных BFS.
Тот же трюк обобщается: мультиисточниковая Дейкстра (кладём все источники с dist=0 в кучу) даёт расстояние до ближайшего источника во взвешенном графе. И ещё — этим решают «01 Matrix» и задачи про «волну от всех заражённых одновременно»: засекаешь, на каком слое последняя клетка стала достигнута — это ответ на «через сколько шагов всё охвачено».