Skip to content
Menu
Portfolio
  • Artificial Intelligence
  • Personal Projects
  • Assignments
  • Algorithms
  • Notes
  • Home
Portfolio

Shortest Path Algorithms

Posted on August 25, 2025August 25, 2025

The following chart illustrates the decision flow for solving shortest path problems.


The Python templates for each algorithm are as follows:

Naive Dijkstra’s Algorithm – Used for Dense Graph

# n is number of nodes, g is the graph created
def dijkstra_naive_matrix(n, g):
    dist = [INF] * (n + 1)
    state = [False] * (n + 1) #record if a mininum dist confirmed or not
    dist[1] = 0

    for _ in range(n - 1):
        t = -1  # find the node t with mininum dist
        for j in range(1, n + 1):
            if not state[j] and (t == -1 or dist[j] < dist[t]):
                t = j
        if t == -1:  # rest nodes are unreachable
            break

        for j in range(1, n + 1):
            if dist[j] > dist[t] + g[t][j]:
                dist[j] = dist[t] + g[t][j]
        state[t] = True

    return -1 if dist[n] >= INF else dist[n]

Heap-Optimized Dijkstra’s Algorithm – Used for Sparse Graph

# n is number of nodes, adj is the adjacency list created
def dijkstra_heap(n, adj):
    dist = [INF] * (n + 1)
    st = [False] * (n + 1)
    dist[1] = 0
    heap = [(0, 1)]  # (distance, node)

    while heap:
        d, u = heapq.heappop(heap)
        if st[u]:
            continue
        st[u] = True
        for v, w in adj[u]:
            if dist[v] > d + w:
                dist[v] = d + w
                heapq.heappush(heap, (dist[v], v))

    return -1 if dist[n] >= INF else dist[n]

Bellman-Ford Algorithm

INF = 10**9  # large sentinel for "infinity"

def bellman_ford(n, edges):
    dist = [INF] * (n + 1)
    dist[1] = 0

    # Relax edges up to n - 1 times
    for _ in range(n - 1):
        updated = False
        for a, b, w in edges:
            if dist[a] < INF and dist[b] > dist[a] + w:
                dist[b] = dist[a] + w
                updated = True
        # Optimization: stop early if no update
        if not updated:
            break
    """      
    # check one more time for negative cycle
    for a, b, w in edges:
        if dist[a] < INF and dist[b] > dist[a] + w:
            return "negative cycle exist"
    """

    # If still unreachable
    if dist[n] > INF // 2:
        return -1
    return dist[n]

SPFA

from collections import deque

INF = float('inf')

def spfa(n, adj):
    dist = [INF] * (n + 1)
    in_queue = [False] * (n + 1)

    dist[1] = 0
    q = deque([1])
    in_queue[1] = True

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

        for v, w in adj[u]:
            if dist[v] > dist[u] + w:
                dist[v] = dist[u] + w
                if not in_queue[v]:
                    q.append(v)
                    in_queue[v] = True

    return -1 if dist[n] == INF else dist[n]

Use SPFA to determine whether a graph contains a negative cycle

from collections import deque

INF = float('inf')

def has_negative_cycle(n, adj):
    dist = [0] * (n + 1)
    cnt = [0] * (n + 1)
    
    q = deque()
    for i in range(1, n + 1):
        q.append(i)
      
    in_queue = [True] * (n + 1)

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

        for v, w in adj[u]:
            if dist[v] > dist[u] + w:
                dist[v] = dist[u] + w
                cnt[v] = cnt[u] + 1
                
                # path to v uses >= n edges -> negative cycle reachable
                if cnt[v] >= n: 
                    return True
                if not in_queue[v]:
                    q.append(v)
                    in_queue[v] = True

    return False

Floyd-Warshall Algorithm

INF = float('inf')

# initialize adj matrix
adj = [[INF] * (n + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    adj[i][i] = 0

# adj[a][b] representing the shortest path between a and b
def floyd(n, adj):
    for k in range(1, n + 1):
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if adj[i][j] > adj[i][k] + adj[k][j]:
                    adj[i][j] = adj[i][k] + adj[k][j]
                    path[i][j] = path[k][j]

CATEGORIES

  • Artificial Intelligence
  • Personal Projects
  • Notes
  • Algorithms

  • University of Maryland
  • CMSC426 - Computer Vision
  • CMSC320 - Introduction to Data Science
  • CMSC330 - Organization of Programming Languages
  • CMSC216 - Introduction to Computer Systems
©2025 Portfolio | WordPress Theme by Superbthemes.com