Breadth-First Search
    
    Breadth-first search: a method to search a graph and an
    exemplar of many important graph algorithms. Given G = ( V, E ), chose a
    vertex, s, to be the source. Move out from s, systematically to find
    all v Î V that are accessible from s, and
    compute their distances from s. Distance from s to v is the "shortest
    path". 
    Words: start at s, find all vertices distance 1 from
    s, keep going until all vertices have been discovered. 
    Dye analogy: s is the dye injection point and you
    watch the progress of the dye through the graph. Each time step a single
    edge is crossed. In breadth-first search, each vertex is colored: 
    
      - 
        
White: not yet discovered  
      - 
        
Gray: discovered but still some undiscovered adjacent
        vertices .  
      - 
        
Black: discovered and all adjacent vertices discovered  
     
    Gray vertices are the frontier/interface between
    discovered/undiscovered. 
    Constructing a breadth-first tree: 
    
      - 
        
Start with s (the root)  
      - 
        
Scan the adjacency list of all previously discovered
        nodes. If u was previously discovered and we just found v, then we add
        v. u is the predecessor/parent of v in the breadth-first tree.  
     
    This progresses, iteratively. Note: Start with all nodes
    white. When you first encounter a white node, you make it gray. When you go
    through that node's adjacency list, you make it black. 
    Code: Store 
    
      - 
        
Color (white or gray or black)  
      - 
        
Predecessor p[n]  
      - 
        
Distance from s d[n]  
     
    
      BFS ( G, s ) 
      
        - 
          
for each vertex u Î V[G] -
          {s}  
        - 
          
   do color [u] ¬ white 
          // white out all but s  
        - 
          
     d[u] ¬
          ¥  
        - 
          
     p[u]
          ¬ nil  
        - 
          
color [s] ¬ gray // s
          starts out gray  
        - 
          
d[s] ¬ 0  
        - 
          
p[s] ¬
          nil  
        - 
          
Q ¬ {s} // end
          initialization  
        - 
          
while Q ¹ Æ  
        - 
          
   do u ¬ head[Q]  
        - 
          
      for each v Adj[u]  
        - 
          
         do if
          color[v] = white  
        - 
          
             
          then color[v] ¬ gray  
        - 
          
                
          d[v] ¬ d[u] + 1  
        - 
          
                  
          p[v] ¬ u  
        - 
          
                 
          Enqueue ( Q, v )  
        - 
          
       Dequeue ( Q ) //
          Q stores grays  
        - 
          
       color[u] ¬
          black // all of u's adjacents have been seen, so color it black
          and
                                      
          //  move on  
       
        
     
    Running time of Breadth-First search: 
    
      - 
        
Each node is enqueued once (white ®
        gray)  
      - 
        
Each node is dequeued once (gray ® black)  
      - 
        
Each adjacency list is scanned only once.  
     
    
      
        - 
          
O ( | V | )  
        - 
          
O ( | V | )  
        - 
          
O ( | E | )  
       
     
    Overall running time is O ( | V | + | E | ). Clearly
    better to use the adjacency list representation. (What differs with the
    matrix representation?) 
    Shortest-path distance: d ( s, v
    ) is the minimum number of  edges in any path from s to v, or ¥
    if there is no path. A path from s to v with distance d
    ( s, v ) is a shortest-path. Note, there may be more than one shortest path. 
    Lemma: Let G = ( V, E ) be a graph, s Î
    V an arbitrary vertex, then " ( u, v
    ) Î E d ( s, v ) £
    d ( s, v ) + 1. If u is reachable from s, then it holds. If not then
    both d ( s, v ) = ¥ and
    it holds. 
    Suppose BFS is run on G from s. " v
    Î V d[v] ³ d ( s, v
    ) 
    
       Induction on vertices: 
      
        - 
          
d[s] = 0 = d ( s, s )  
        - 
          
d[v] =  ¥ ³ d ( s, v
          ) " s ¹ v
          at the first step  
       
      
        v is discovered from u (u is at the head of Q), v is
        white. 
       
      Induction when u is at the head of Q 
      
        Assume d[u] ³ d ( s, v ) 
        d[v] = d[u] + 1 
               ³
        d ( s, v )  + 1 
              
        ³ d ( s, v ) 
        Proved. 
       
     
    Suppose during BFS Q contains v1, ... vv)
    Þ d[vv] £ d[v1], 
    d[vi] £ d[vi+1], i = 1,
    ..., v - 1 
    
      Proof: 
      
        Induction on queue operations. 
        
          - 
            
When Q = <s> it holds  
          - 
            
Must prove it holds after both dequeuing and
            enqueuing a vertex when v1 is is dequeued v2 becomes
            the head  
         
        
          d[vr] £ d[v1]
          + 1 £ d[v2] + 1           
          Ö 
         
        What happens we enqueue? vv+1 is enqueued
        Adj[v1] vv+1. 
        
          d[vv+1] = d[v1] + 1         
          Ö 
          d[vv] £ d[v1]
          + 1 = d[vv+1]
                    Ö 
         
       
     
    Let G = ( V, E ) and s Π V
    for BFS. 
    
      - 
        
BFS discovers all v Π V
        that are reachable from s  
      - 
        
d[v] = d ( s, v ) "
        v Π V (even ¥)  
      - 
        
" v ¹
        s reachable, a shortest path is the shortest path from s to p[v]
        followed on ( p[v], v )  
     
    
      Proof: 
      
        If v is unreachable it's true. d[v] = ¥
        = d ( s, v ). If v is reachable from s
        define: 
        
          Vk = { v Î V: d
          ( s, v ) = k} 
         
        Inductions on k, " v Î
        Vk 
        
        
          the above 4 bullets all happen during the same loop 
         
        k = 0 = V0 {s}
                  Ö
         
        Q is never empty until the end. Once u is enqueued, d[u]
        and p[u] are set and do not change. From
        previous results we have that d[vi] £ d[vi+1],
        and v Î Vk Þ
        d[v] ³ k and v is discovered after all Vk-1
        vertices are enqueued. Since d ( s, v )
        = k $ u Î Vk-1
        '( u, v ) Î E.
        Let u be the first of these grayed. U  must also eventually appear
        at the head of Q, when it is Adj[u] is scanned and v is discovered, this
        is the first time it could be (would be in Vk-1,
        then).  
        
          BFS: 
          
            d[v] = d[u] + 1 
            p[v] = u 
            enqueues
                      Ö
             
           
         
         This proof by induction is done.  (Clearly ( p[u],
        u )is in a shortest path.) 
       
     
    Breadth-First Trees: 
    
      G = ( V, E ), s Î V source. G
      = ( Vp, Ep
      ) is the predecessor sub graph. Vp =
      { v Î V | p[v] ¹
      nil } v {s} (accessible vertices) Ep
      = { ( p[v], v )  Î E
      :  v Î Vp
      - {s}} (tree edges) . Gp  is a
      breadth first tree. " v Π
      Vp $  a unique simple path
      from s to v. 
      BFS to G constructs p so Gp
      is a BF Tree.  
      Proof:  
      
        v Î Vp 
        only if reachable p[v] = u only if ( v, v ) E
        by previous the unique path must be the shortest. 
       
      Print-Path ( G, s, v ) 
      
        - 
          
if v = s   
        - 
          
   then print s  
        - 
          
   else if p[v] =
          nil  
        - 
          
      then print "no
          path from " s "  to " v " exists"  
        - 
          
      else Print-Path ( G, s,
          p[v] )  
        - 
          
         print
          v  
       
      Prints out the vertices from s to b in G. 
        
      
          
       
        
     
   |