2#include <boost/graph/adjacency_list.hpp> 
    3#include <boost/graph/breadth_first_search.hpp> 
    7template <
typename IndexMap = 
identity_property_map>
 
    8struct two_bit_color_map_fast
 
   12  mutable std::vector<unsigned char> data;
 
   14  BOOST_STATIC_CONSTANT(
int, bits_per_char = std::numeric_limits<unsigned char>::digits);
 
   15  BOOST_STATIC_CONSTANT(
int, elements_per_char = bits_per_char / 2);
 
   16  typedef typename property_traits<IndexMap>::key_type key_type;
 
   17  typedef two_bit_color_type value_type;
 
   18  typedef void reference;
 
   19  typedef read_write_property_map_tag category;
 
   21  explicit two_bit_color_map_fast(std::size_t n, 
const IndexMap& index = IndexMap())
 
   24      , data((n + elements_per_char - 1) / elements_per_char)
 
   27    std::fill(data.begin(), data.end(), 0);
 
   30  void resize(std::size_t n)
 
   33    data.resize((n + elements_per_char - 1) / elements_per_char);
 
   34    std::fill(data.begin(), data.end(), 0);
 
   38template <
typename IndexMap>
 
   39inline two_bit_color_type
 
   40get(
const two_bit_color_map_fast<IndexMap>& pm,
 
   41    typename property_traits<IndexMap>::key_type key)
 
   43  BOOST_STATIC_CONSTANT(
 
   44      int, elements_per_char = two_bit_color_map_fast<IndexMap>::elements_per_char);
 
   45  typename property_traits<IndexMap>::value_type i = get(pm.index, key);
 
   46  BOOST_ASSERT((std::size_t)i < pm.n);
 
   48  std::size_t byte_num = i / elements_per_char;
 
   49  std::size_t bit_position = ((i % elements_per_char) * 2);
 
   51  return two_bit_color_type((pm.data[byte_num] >> bit_position) & 3);
 
   54template <
typename IndexMap>
 
   56put(
const two_bit_color_map_fast<IndexMap>& pm,
 
   57    typename property_traits<IndexMap>::key_type key, two_bit_color_type value)
 
   59  BOOST_STATIC_CONSTANT(
 
   60      int, elements_per_char = two_bit_color_map_fast<IndexMap>::elements_per_char);
 
   61  typename property_traits<IndexMap>::value_type i = get(pm.index, key);
 
   62  BOOST_ASSERT((std::size_t)i < pm.n);
 
   63  BOOST_ASSERT(value >= 0 && value < 4);
 
   65  std::size_t byte_num = i / elements_per_char;
 
   66  std::size_t bit_position = ((i % elements_per_char) * 2);
 
   69      = (
unsigned char)((pm.data[byte_num] & ~(3 << bit_position)) | (value << bit_position));
 
   72template <
typename IndexMap>
 
   73inline two_bit_color_map_fast<IndexMap>
 
   74make_two_bit_color_map_fast(std::size_t n, 
const IndexMap& index_map)
 
   76  return two_bit_color_map_fast<IndexMap>(n, index_map);
 
   84    class IncidenceGraph, 
class Vertex, 
class Buffer, 
class BFSVisitor, 
class ColorMap>
 
   85void breadth_first_visit_simple(
 
   86    const IncidenceGraph& g, Vertex source, Buffer& Q, BFSVisitor& vis, ColorMap& color)
 
   88  using namespace boost;
 
   89  using GTraits = graph_traits<IncidenceGraph>;
 
   90  typename GTraits::out_edge_iterator ei, ei_end;
 
   92  BOOST_CONCEPT_ASSERT((IncidenceGraphConcept<IncidenceGraph>));
 
   94  put(color, source, two_bit_gray);
 
   95  vis.discover_vertex(source, g);
 
  100    Vertex u = Q.front();
 
  102    for(std::tie(ei, ei_end) = out_edges(u, g); ei != ei_end; ++ei)
 
  104      Vertex v = target(*ei, g);
 
  105      auto v_color = get(color, v);
 
  106      if(v_color == two_bit_white)
 
  108        put(color, v, two_bit_gray);
 
  109        if(vis.discover_vertex(v, g))
 
  114    put(color, source, two_bit_black);
 
  118template <
class VertexListGraph, 
class Visitor, 
class Queue, 
class ColorMap>
 
  119void breadth_first_search_simple(
 
  120    const VertexListGraph& g,
 
  121    typename boost::graph_traits<VertexListGraph>::vertex_descriptor s, Visitor& vis,
 
  122    Queue& Q, ColorMap& color)
 
  124  using namespace boost;
 
  128  typename boost::graph_traits<VertexListGraph>::vertex_iterator i, i_end;
 
  129  for(boost::tie(i, i_end) = vertices(g); i != i_end; ++i)
 
  130    put(color, *i, two_bit_white);
 
  132  breadth_first_visit_simple(g, s, Q, vis, color);