api: "YAML JSON TOON Database"
version: "1.0.0"
format: "json"
dataset:
  id: 26
  slug: "graph-algorithms"
  title: "Graph Algorithms"
  description: "Essential graph algorithms: traversals (BFS, DFS), shortest path (Dijkstra, Bellman-Ford), minimum spanning tree (Prim, Kruskal), topological sort, and network flow."
  category: "Data Structures"
  category_slug: "data-structures"
  tags: "graphs,algorithms,bfs,dfs,dijkstra,mst,topological-sort,network-flow"
  view_count: 0
  created_at: 1777673262
  updated_at: 1777673262
data:
  algorithms:
    - name: "Breadth-First Search (BFS)"
      category: "Traversal"
      time_complexity: "O(V + E)"
      space_complexity: "O(V)"
      description: "Visits nodes level by level using queue; finds shortest path in unweighted graphs."
      use_cases:
        - "Shortest path (unweighted)"
        - "Web crawling"
        - "Social network friend suggestions"
        - "Garbage collection (mark-sweep)"
      pseudocode: "queue ← [start]; visited ← {start}; while queue not empty: node ← queue.pop(); for each neighbor of node: if neighbor not visited: visited.add(neighbor); queue.push(neighbor)"
      notes: "Guarantees shortest path in unweighted graphs; uses more memory than DFS"
    - name: "Depth-First Search (DFS)"
      category: "Traversal"
      time_complexity: "O(V + E)"
      space_complexity: "O(V) (recursion stack or explicit stack)"
      description: "Explores as far as possible along each branch before backtracking; uses stack (implicit or explicit)."
      use_cases:
        - "Cycle detection"
        - "Topological sorting"
        - "Maze solving"
        - "Connected components"
        - "Path existence"
      pseudocode: "stack ← [start]; visited ← {}; while stack not empty: node ← stack.pop(); if node not visited: visited.add(node); for each neighbor of node: if neighbor not visited: stack.push(neighbor)"
      notes: "Lower memory footprint than BFS; can get stuck in deep infinite branches (use iterative deepening or IDDFS)"
    - name: "Dijkstra's Algorithm"
      category: "Shortest Path"
      time_complexity: "O((V + E) log V) with min-heap, O(V²) with array"
      space_complexity: "O(V)"
      description: "Single-source shortest path for graphs with non-negative edge weights."
      input_requirements: "Weighted directed/undirected graph; all edge weights ≥ 0"
      pseudocode: "dist[start] ← 0; pq ← min-heap of (distance, node); while pq not empty: d, u ← pq.pop(); if d > dist[u]: continue; for each edge u→v with weight w: if dist[u] + w < dist[v]: dist[v] ← dist[u] + w; pq.push(dist[v], v)"
      notes: "Fails with negative weights (use Bellman-Ford); can be optimized with Fibonacci heap (O(V log V + E))"
    - name: "Bellman-Ford Algorithm"
      category: "Shortest Path"
      time_complexity: "O(V × E)"
      space_complexity: "O(V)"
      description: "Single-source shortest path handling negative weights; detects negative cycles."
      input_requirements: "Weighted directed graph; negative weights allowed but no negative cycles reachable from source"
      pseudocode: "dist[all] ← ∞; dist[source] ← 0; repeat V-1 times: for each edge (u,v,w): if dist[u] + w < dist[v]: dist[v] ← dist[u] + w; // Check negative cycle: for each edge (u,v,w): if dist[u] + w < dist[v]: negative cycle exists"
      notes: "Slower than Dijkstra but handles negatives; used in currency arbitrage detection; SPFA is optimization in practice"
    - name: "Floyd-Warshall Algorithm"
      category: "All-Pairs Shortest Path"
      time_complexity: "O(V³)"
      space_complexity: "O(V²)"
      description: "All-pairs shortest paths for dense graphs; works with negative weights (no negative cycles)."
      input_requirements: "Directed/undirected weighted graph; no negative cycles"
      pseudocode: "for k from 1 to V: for i from 1 to V: for j from 1 to V: dist[i][j] ← min(dist[i][j], dist[i][k] + dist[k][j])"
      notes: "Simple triple loop; good for dense graphs (V² space); transitive closure variant"
    - name: "Prim's Algorithm"
      category: "Minimum Spanning Tree"
      time_complexity: "O(E log V) with min-heap, O(V²) with array"
      space_complexity: "O(V)"
      description: "Grows MST from a starting node; always adds cheapest edge connecting tree to new vertex."
      pseudocode: "start ← arbitrary node; mst_set ← {start}; while |mst_set| < V: find minimum weight edge (u,v) where u in mst_set, v not in mst_set; add v to mst_set; add edge to MST"
      notes: "Like Dijkstra but tracks vertices instead of distances; better for dense graphs"
    - name: "Kruskal's Algorithm"
      category: "Minimum Spanning Tree"
      time_complexity: "O(E log E) (sorting dominates)"
      space_complexity: "O(V)"
      description: "Builds MST by adding edges in increasing weight order, skipping those that create cycles."
      pseudocode: "sort edges by weight; mst ← {}; for each edge (u,v,w) in sorted edges: if find(u) ≠ find(v): mst.add(edge); union(u,v); // uses Disjoint Set (Union-Find)"
      notes: "Better for sparse graphs; requires Union-Find with path compression (α(n) ≈ constant)"
    - name: "Topological Sort"
      category: "Ordering"
      time_complexity: "O(V + E)"
      space_complexity: "O(V)"
      description: "Linear ordering of DAG vertices such that for every edge u→v, u comes before v."
      algorithms:
        - "Kahn's (BFS-based: indegree zero queue)"
        - "DFS-based (postorder reverse)"
      pseudocode_kahn: "compute indegree of all nodes; queue ← all nodes with indegree 0; while queue not empty: u ← queue.pop(); order.append(u); for each neighbor v of u: indegree[v]--; if indegree[v] == 0: queue.push(v); if order.size < V: cycle detected"
      use_cases:
        - "Task scheduling (build systems, job queues)"
        - "Course prerequisites"
        - "Dependency resolution"
        - "Makefiles"
      notes: "Graph must be DAG; detects cycles; Kahn's also detects cycles"
    - name: "Union-Find (Disjoint Set)"
      category: "Connectivity"
      time_complexity: "O(α(n)) per operation (amortized nearly O(1))"
      space_complexity: "O(n)"
      description: "Track partition of elements into disjoint sets; supports union and find operations."
      operations:
        find: "Returns representative (root) of set containing element; uses path compression"
        union: "Merges two sets; uses union by rank/size"
      use_cases:
        - "Kruskal's MST"
        - "Connected components"
        - "Maze generation (Kruskal's)"
        - "Percolation"
      notes: "Path compression + union by rank gives amortized α(n) ≈ constant (inverse Ackermann); one of most optimized DS"
    - name: "Ford-Fulkerson (Max Flow)"
      category: "Network Flow"
      time_complexity: "O(E × max_flow) — Edmonds-Karp is O(V × E²)"
      space_complexity: "O(V + E)"
      description: "Computes maximum flow from source to sink in flow network; Ford-Fulkerson method with augmenting paths."
      variants:
        - "Edmonds-Karp (BFS augmenting paths, O(VE²))"
        - "Dinic's (O(V²E), blocking flows)"
        - "Push-relabel (O(V³))"
      use_cases:
        - "Bipartite matching"
        - "Assignment problems"
        - "Network capacity planning"
        - "Image segmentation (min-cut)"
      notes: "Integral capacities → integral flow; Dinic's is faster in practice for dense graphs"
  graph_representations:
    adjacency_matrix:
      space: "O(V²)"
      pros:
        - "O(1) edge lookup"
        - "Simple"
        - "Good for dense graphs"
      cons:
        - "O(V²) space even if sparse"
        - "Iterating neighbors O(V)"
    adjacency_list:
      space: "O(V + E)"
      pros:
        - "Space efficient for sparse graphs"
        - "Fast neighbor iteration"
      cons:
        - "O(degree(v)) edge existence check"
        - "Slower for dense graphs"
    edge_list:
      space: "O(E)"
      pros:
        - "Simple"
        - "Good for algorithms that process all edges (Kruskal)"
      cons:
        - "Slow edge lookup O(E)"
        - "No fast neighbor access"
