# `depth_first_search`

Graphs: | directed and undirected
Properties: | color
Complexity: | time: O(V + E)
Where Defined: | `boost/graph/depth_first_search.hpp`

    (1)
    template <class VertexListGraph, class DFSVisitor>
    void depth_first_search(VertexListGraph& G, DFSVisitor v);

    (2)
    template <class VertexListGraph, class DFSVisitor, class ColorMap>
    void depth_first_search(VertexListGraph& G, DFSVisitor v, ColorMap c);

The `depth_first_search()` algorithm performs a depth-first search (DFS) on a graph, invoking the methods of the graph search visitor at the appropriate event-points. A depth-first search visits all the vertices in a graph, starting with some arbitrary vertex and then always choosing the next adjacent unvisited vertex. Once the DFS reaches a vertex with no unvisited neighbors it backtracks to one of the previous vertices and continues from there. Once all of the vertices in the same connected component have been visited, another arbitrary unvisited vertex is choosen and the depth-first search resumes. A more detailed explanation of DFS is given in Section Depth-First Search. The depth-first exploration of each connected component is implemented by the function `depth_first_visit()`.

The `DFSVisitor` supplied by the user determines what actions are taken at each event-point within the algorithm.

The `ColorMap` is used by the algorithm to keep track of which vertices have been visited.

DFS is used as the kernel for several other graph algorithms, including `topological_sort` and two of the connected component algorithms.

### Requirements on Types

- The type `VertexListGraph` must be a model of VertexListGraph.
- In version (1) of the algorithm the graph must be a model of PropertyGraph for `vertex_color_t` and the color property map for the graph must meet the same requirements as `ColorMap`.
- The type `ColorMap` must be a model of ReadWritePropertyMap. The key type of `ColorMap` must be the vertex descriptor type for the graph and the value type of `ColorMap` must be a model of ColorValue.
- The `DFSVisitor` type must be a model of DFSVisitor.

### Complexity

The time complexity is O(E + V).

### Example

This example shows DFS applied to the graph in Figure 1. The source code for this example is in `examples/dfs_basics.cpp`.

Figure 1: Depth-first search spreading through a graph.

      // Select the graph type we wish to use
      typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS> Graph;
      // Set up the vertex names
      enum { u, v, w, x, y, z, N };
      char name[] = { 'u', 'v', 'w', 'x', 'y', 'z' };
      // Specify the edges in the graph
      typedef std::pair<int,int> E;
      E edge_array[] = { E(u,v), E(u,x), E(x,v), E(y,x),
                         E(v,y), E(w,y), E(w,z), E(z,z) };
      Graph G(N, edge_array, edge_array + sizeof(edge_array)/sizeof(E));

      // Some typedef's to save a little typing
      typedef boost::graph_traits<Graph>::vertex_descriptor Vertex;
      typedef boost::graph_traits<Graph>::vertices_size_type size_type;
      typedef std::vector<Vertex>::iterator Piter;
      typedef std::vector<size_type>::iterator Iiter;

      // color, discover time, and finish time properties
      std::vector<default_color_type> color(num_vertices(G));
      std::vector<size_type> dtime(num_vertices(G));
      std::vector<size_type> ftime(num_vertices(G));

      boost::depth_first_search(G, boost::visit_timestamp(dtime.begin(), ftime.begin()),
                                color.begin());

      // use std::sort to order the vertices by their discover time
      std::vector<size_type> discover_order(N);
      boost::iota(discover_order.begin(), discover_order.end(), 0);
      std::sort(discover_order.begin(), discover_order.end(),
        boost::indirect_cmp<Iiter, std::less<size_type> >(dtime.begin()));

      std::cout << "order of discovery: ";
      for (int i = 0; i < N; ++i)
        std::cout << name[ discover_order[i] ] << " ";

      std::vector<size_type> finish_order(N);
      boost::iota(finish_order.begin(), finish_order.end(), 0);
      std::sort(finish_order.begin(), finish_order.end(),
        boost::indirect_cmp<Iiter, std::less<size_type> >(ftime.begin()));

      std::cout << endl << "order of finish: ";
      for (size_type i = 0; i < N; ++i)
        std::cout << name[ finish_order[i] ] << " ";
      std::cout << std::endl;

The output is:

    order of discovery: u v y x w z
    order of finish: x y v u z w

### See Also

`depth_first_visit`

Copyright © 2000 | Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) Lie-Quan Lee, Univ.of Notre Dame (llee1@lsc.nd.edu) Andrew Lumsdaine, Univ.of Notre Dame (lums@lsc.nd.edu)