Как работает алгоритм Дейкстры?
- Как найти кратчайший путь во взвешенном графе?
- Почему Дейкстра не работает с отрицательными весами?
- Какая сложность у алгоритма Дейкстры?
Дейкстра находит кратчайшие пути от одной вершины во взвешенном графе с неотрицательными весами: каждый раз берёт ближайшую ещё не обработанную вершину и ослабляет рёбра из неё.
- Ближайшую вершину достают из очереди с приоритетом (кучи): O((V + E) log V)
- Когда вершину достали из очереди, расстояние до неё окончательное
А ещё Отрицательные веса ломают это свойство — нужен Беллман — Форд
Подробно
Идея. Храним текущие оценки расстояний dist: у старта 0, у остальных бесконечность. Повторяем:
- достать из очереди с приоритетом вершину
vс наименьшимdist; - для каждого ребра
v → uс весомw: еслиdist[v] + w < dist[u], обновитьdist[u]и положитьuв очередь (это называется ослаблением ребра); - запоминать родителя, чтобы восстановить путь.
Почему это верно. Все веса неотрицательны, поэтому вершина, у которой сейчас наименьшая оценка, не может получить ещё меньшую через другие вершины — любой обходной путь только длиннее. Значит, в момент извлечения её расстояние окончательное. Это «жадный» шаг.
Отрицательные веса ломают рассуждение: обходной путь через отрицательное ребро может оказаться короче уже «окончательного». Для них используют алгоритм Беллмана — Форда (O(V·E)), он же находит отрицательные циклы.
Сложность с двоичной кучей — O((V + E) log V). Для невзвешенного графа Дейкстра вырождается в BFS. Если нужен путь до одной конкретной цели, можно остановиться, когда цель извлечена из очереди, а ещё лучше — использовать A* с эвристикой.
Применения: маршрутизация в сетях (OSPF), навигация, стоимость перемещения в играх.
Пример
import heapq
def dijkstra(graph, start):
dist = {start: 0}
heap = [(0, start)]
while heap:
d, v = heapq.heappop(heap)
if d > dist.get(v, float("inf")):
continue # устаревшая запись в куче
for u, w in graph[v]:
nd = d + w
if nd < dist.get(u, float("inf")):
dist[u] = nd
heapq.heappush(heap, (nd, u))
return distЧто хотят услышать
- Жадный выбор ближайшей вершины и ослабление рёбер.
- Роль очереди с приоритетом и сложность.
- Почему нельзя отрицательные веса и что вместо.
- Связь с BFS и A* — плюс.
Частые ошибки
- Применять к графу с отрицательными весами.
- Забыть пропускать устаревшие записи в куче.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗Дейкстра перебирает все пути между двумя вершинами и выбирает минимальный; корректно работает и с отрицательными весами рёбер
- ✓Дейкстра берёт ближайшую необработанную вершину из очереди с приоритетом и ослабляет рёбра; работает при неотрицательных весах
- ✗Дейкстра находит пути только между двумя соседними вершинами
- ✗Расстояние до извлечённой вершины может уменьшиться позже
Что спросят дальше
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.