Skip to content

Bellman Ford Algorithm

Bellman-Ford Algorithm

\(O(VE)\)

def bellman_ford(graph, src):
    # graph format: {"node1", [("node2", 10)]}
    dist = {node: float('inf') for node in graph}
    dist[src] = 0

    n = len(graph)
    for _ in range(n - 1): # at most n-1 edge from src to dst
        for n1, (n2, weight) in graph.items():
            dist[n2] = min(dist[n2], dist[n1] + weight)

    # optional: detect negative cycles
    for n1, (n2, weight) in graph.items():
        if dist[n1] + weight < distances[n2]:
            raise ValueError("Graph contains a negative-weight cycle")

    return distances

optimized with queue - Shortest Path Faster Algorithm SPFA

Use a queue to store updated nodes and only calculate the updated nodes.

from collections import deque

def spfa(graph, start):
    distances = {node: float('inf') for node in graph}
    in_queue = {node: False for node in graph}
    count = {node: 0 for node in graph}

    distances[start] = 0
    queue = deque([start])
    in_queue[start] = True # to prevent duplicate enqueue

    while queue:
        u = queue.popleft()
        in_queue[u] = False

        for v, weight in graph[u]:
            if distances[u] + weight < distances[v]:
                distances[v] = distances[u] + weight
                if not in_queue[v]:
                    queue.append(v)
                    in_queue[v] = True
                    count[v] += 1
                    if count[v] > len(graph):
                        raise ValueError("Negative-weight cycle detected")

    return distances