← Все вопросы
Как посчитать количество кратчайших путей между двумя вершинами?
9
Нужна не длина кратчайшего пути из s в t, а сколько разных кратчайших путей существует (по модулю, число большое). Граф невзвешенный. Как это сделать вместе с BFS?
2 ответа
13
✓ Принятый ответ — помог автору
Ведём два массива: dist[v] (длина кратчайшего пути) и ways[v] (число кратчайших путей до v). При BFS, когда из v идём в соседа u:
- если нашли
uвпервые (dist[u]ещё не установлено) →dist[u] = dist[v]+1,ways[u] = ways[v]; - если пришли в
uснова по кратчайшему (dist[v]+1 == dist[u]) →ways[u] += ways[v].
const int MOD = 1e9+7;
vector<int> dist(n, -1), ways(n, 0);
queue<int> q;
dist[s] = 0; ways[s] = 1; q.push(s);
while (!q.empty()) {
int v = q.front(); q.pop();
for (int u : g[v]) {
if (dist[u] == -1) {
dist[u] = dist[v] + 1;
ways[u] = ways[v];
q.push(u);
} else if (dist[u] == dist[v] + 1) {
ways[u] = (ways[u] + ways[v]) % MOD;
}
}
}
// ответ: ways[t]
Сложность O(V + E). ways обычно считают по модулю — число путей растёт экспоненциально.
6
Для взвешенного графа то же делается поверх Дейкстры, но аккуратнее: при строгом улучшении dist[u] мы перезаписываем ways[u] = ways[v] (старые пути перестали быть кратчайшими), а при равенстве dist[v]+w == dist[u] — прибавляем ways[u] += ways[v]. Главная грабля — не забыть сбрасывать счётчик при улучшении расстояния, иначе насчитаете лишнего от уже неактуальных путей.
Ваш ответ
Войдите, чтобы ответить на вопрос.