Что делает: находит кратчайшие расстояния от одной вершины до всех остальных в взвешенном ориентированном графе
Чего | Точная оценка | Почему |
---|---|---|
Время | O(VE) | O([V-1]*E + E) == O(VE): V-1 раз проходимся по всем рёбрам релаксируя (релаксация за O(1)) ⇒ O([V-1]*E) + O(E) - проверка на отрицательные циклы |
Память | O(V) | похуй |
Общая идея:
Для каждой вершины прорелаксировать рёбра со всеми остальными вершинами. Из-за леммы о том, что часть кратчайшего расстояния == кратчайшее расстояние, все классно работает (на каждой итерации 100% правильно релаксируем одно ребро)
Также алгоритм может определить циклы отрицательного веса: после всех релаксаций, прорелаксировать каждое ребро ещё один раз, и если хоть одно изменится ⇒ существует цикл отрицательного веса
Реализация:
int main() {
for u из G(V) do {
u.distance = INF
u.parent = NULL
}
s.distance = 0 // инициализируем стартовую вершину
for i = 1 to (|V|-1) do
for edge(u,v) из edges do
Relax(edge(u,v)) // передаем u -> v and weight
for edge(u,v) из edges do
if v.distance > u.distance + weight(u,v)
return "Цикл отрицательного веса!"
}
void Relax(edge) {
v.distance = min(v.distance, u.distance + edge.weight)
if v.distance changes:
v.parent = u
}
‼ Особенности алгоритма Беллмана-Форда:
Визуализация: этим я займусь чуть попозже