Graph Algorithms

📖 Introduction

Graph algorithms power the infrastructure we use daily—navigation apps finding shortest routes, social networks suggesting connections, and compilers determining build order. When I first implemented Dijkstra's algorithm for a routing project, the elegance of how it systematically finds optimal paths amazed me.

This article covers the essential graph algorithms you'll encounter repeatedly: shortest paths, minimum spanning trees, topological sorting, and the powerful Union-Find data structure.


🛤️ Shortest Path Algorithms

BFS for Unweighted Graphs

from collections import deque
from typing import Dict, List, Optional

def bfs_shortest_path(
    graph: Dict[str, List[str]], 
    start: str, 
    end: str
) -> Optional[List[str]]:
    """
    Find shortest path in unweighted graph.
    Time: O(V + E)
    """
    if start == end:
        return [start]
    
    visited = {start}
    queue = deque([(start, [start])])
    
    while queue:
        node, path = queue.popleft()
        
        for neighbor in graph[node]:
            if neighbor == end:
                return path + [neighbor]
            
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append((neighbor, path + [neighbor]))
    
    return None

Dijkstra's Algorithm

For graphs with non-negative edge weights.

spinner

Bellman-Ford Algorithm

Handles negative edge weights, detects negative cycles.

Floyd-Warshall Algorithm

All-pairs shortest paths.

Algorithm Comparison

Algorithm
Time
Space
Negative Weights
Use Case

BFS

O(V+E)

O(V)

N/A (unweighted)

Unweighted shortest path

Dijkstra

O((V+E)logV)

O(V)

No

Single-source, positive weights

Bellman-Ford

O(VE)

O(V)

Yes

Negative weights, detect cycles

Floyd-Warshall

O(V³)

O(V²)

Yes

All-pairs shortest paths


🌲 Minimum Spanning Tree

A spanning tree that connects all vertices with minimum total edge weight.

Prim's Algorithm

Grow MST from a starting vertex.

Kruskal's Algorithm

Sort edges, add if doesn't create cycle (using Union-Find).


🔗 Union-Find (Disjoint Set Union)

Efficiently track connected components.

Union-Find Applications

Number of Connected Components

Redundant Connection

Accounts Merge


📊 Topological Sort

Linear ordering of vertices in a DAG where for every edge u→v, u comes before v.

spinner

Kahn's Algorithm (BFS)

DFS-Based Topological Sort

Course Schedule II


🎯 Advanced Graph Problems

Cheapest Flights Within K Stops

Alien Dictionary

Critical Connections (Bridges)


📝 Practice Exercises

Exercise 1: Path with Maximum Probability

chevron-rightSolutionhashtag

Exercise 2: Reconstruct Itinerary

chevron-rightSolutionhashtag

Exercise 3: Evaluate Division

chevron-rightSolutionhashtag

🔑 Key Takeaways

  1. BFS for unweighted shortest paths

  2. Dijkstra for non-negative weighted graphs

  3. Bellman-Ford for negative weights and cycle detection

  4. Union-Find for dynamic connectivity problems

  5. Topological sort for dependency ordering

  6. Know when to use which: problem constraints guide algorithm choice


🚀 What's Next?

In the final article, we'll consolidate everything with problem-solving patterns:

  • Pattern recognition strategies

  • Interview approach

  • Common patterns catalog

  • Time management tips

Next: Article 15 - Problem-Solving Patterns


📚 References

  • CLRS Chapters 22-26: Graph Algorithms

  • "Algorithm Design" - Kleinberg & Tardos

  • Competitive programming resources

Last updated