Sunday, March 3rd, 2024

Share your smile with the world. It's a symbol of friendship and peace.

— Christie Brinkley

ECS122A Lecture Notes: DFS

Depth-first Search (DFS)

  • depth-first search
  • input: a graph
  • output:
    • discovery and finish times of each vertex
    • classification of edges
  • vertex color
    • white: undiscovered
    • gray: discovered; has not finished processing
    • black: processing finished (all neighbors visited)
  • edge classification during DFS
    • T (tree edge): encountered new vertex (edge from gray to white)
    • B (back edge): descendant to ancestor (edge from gray to gray)
    • F (forward edge): ancestor to descendant (edge from gray to black)
    • C (cross edge): any other edges (from trees to subtrees) (edge from gray to black)
    • Classify by the first type that matches, since it undirected graphs there can be ambiguity, e.g.
  • recursive procedure
    • DFS
      • Set all vertices’ color to white
      • For each vertex in graph (this is needed because we cannot assume the graph is connected)
        • Visit the vertex if it’s white
    • DFS Visit
      • Mark the vertex as gray
      • Increment time. Save the discovery time
      • Visit each neighboring white vertex
      • Increment time. Save the finish time.
  • in-progress vertices (gray) can be processed in a stack (as opposed to BFS where vertices are processed in a queue)
    • push the node onto the stack when first encountered
    • when visiting the node, pop it, push all of its white neighbors onto the stack, then push the node again to save the finish time later
  • runtime:
    • tight bound, since the algorithm is guaranteed to explore all vertices and all edges

Shortest path finding

  • single-source shortest path (SSSP) problem: given a source vertex in a weighted graph, for each vertex, find the path to this vertex with the minimum weight
  • Bellman-Ford algorithm
    • basic algorithm for path finding
    • can handle negative edge weights
    • input:
      • set of vertices and edges
      • weights of each edge
      • source vertex
    • output:
      • : weight of the shortest path from source to
      • : parent (predecessor) of (can be used to traceback the shortest path)
      • returns true if source won’t reach any negative-weight cycles, false otherwise
    • procedure
      • initialize and for each vertex
      • iterate times
        • for each edge
          • if (if has a shorter path through , relax)
      • for each edge
        • if
          • return false (negative weight cycle found)
      • return true
    • runtime:
  • Dijkstra’s algorithm
    • traits
      • does not handle edges with negative weight
      • BFS-like. Can just use BFS if all edges have the same weight (1).
      • uses , a priority queue keyed by (in contrast, BFS uses a FIFO queue)
    • input
      • set of edges and vertices
      • : weight of edge from to
      • source vertex
    • output
      • : shortest path distance from to
      • : predecessor of (traceback)
    • procedure (with min priority queue)
      • initialize and for each vertex
      • (initialize min priority queue keyed by )
      • while queue is not empty
        • = q.pop() – pop vertex with smallest shortest path weight
        • for each edge , try to update ‘s shortest path weight:
          • if
            • path through neighbor has lower weight, update distance and predecessor
      • return ,
    • runtime
      • with min priority queue
      • without priority queue
    • Dijkstra’s algorithm is greedy (similar to BFS & MFS algorithms, as it replaces the current known path from to if a path through proves to be shorter.
  • DAG single-source shortest path (SSSP) algorithm
    • A DAG can have negative weight edges, but by definition won’t have negative weight cycle (or any cycle for that matter)
    • runtime: , a significant upgrade from Bellman-Ford algorithm
    • procedure
      • topologically sort vertices of
      • initialize and for each vertex
      • for each taken in topological order
        • for each adjacent vertex
          • if
      • return ,