Вступить в клуб →
средняявопросГрафы и обходы

Дейкстра на графе с одним отрицательным ребром

Граф из четырёх вершин: A -> B вес 1, A -> C вес 2, C -> B вес -2, B -> D вес 1. Отрицательных циклов нет.

import heapq


def dijkstra(graph, start):
    dist = {v: float('inf') for v in graph}
    dist[start] = 0
    done = set()
    pq = [(0, start)]
    while pq:
        d, u = heapq.heappop(pq)
        if u in done:
            continue
        done.add(u)
        for v, w in graph[u]:
            if d + w < dist[v]:
                dist[v] = d + w
                heapq.heappush(pq, (dist[v], v))
    return dist

Алгоритм возвращает dist['D'] == 2, хотя настоящий кратчайший путь A -> C -> B -> D стоит 1. Почему?

  • Проблема в heapq: при отрицательных ключах куча не гарантирует правильный порядок извлечения
  • Извлечённая вершина считается окончательной, а отрицательное ребро улучшает её уже после закрытия
  • Достаточно прибавить ко всем весам константу и убрать отрицательные: кратчайший путь от сдвига не меняется
  • Дейкстра ломается только на отрицательном цикле, а отдельное отрицательное ребро обрабатывает корректно

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела