bfs-example2.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //=======================================================================
  2. // Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. //=======================================================================
  8. #include <boost/graph/adjacency_list.hpp>
  9. #include <boost/graph/breadth_first_search.hpp>
  10. #include <boost/pending/indirect_cmp.hpp>
  11. #include <boost/range/irange.hpp>
  12. #include <boost/property_map/property_map.hpp>
  13. #include <iostream>
  14. using namespace boost;
  15. template < typename TimeMap > class bfs_time_visitor:public default_bfs_visitor {
  16. typedef typename property_traits < TimeMap >::value_type T;
  17. public:
  18. bfs_time_visitor(TimeMap tmap, T & t):m_timemap(tmap), m_time(t) { }
  19. template < typename Vertex, typename Graph >
  20. void discover_vertex(Vertex u, const Graph & g) const
  21. {
  22. put(m_timemap, u, m_time++);
  23. }
  24. TimeMap m_timemap;
  25. T & m_time;
  26. };
  27. struct VertexProps {
  28. boost::default_color_type color;
  29. std::size_t discover_time;
  30. unsigned int index;
  31. };
  32. int
  33. main()
  34. {
  35. using namespace boost;
  36. // Select the graph type we wish to use
  37. typedef adjacency_list < listS, listS, undirectedS,
  38. VertexProps> graph_t;
  39. // Set up the vertex IDs and names
  40. enum { r, s, t, u, v, w, x, y, N };
  41. const char *name = "rstuvwxy";
  42. // Specify the edges in the graph
  43. typedef std::pair < int, int >E;
  44. E edge_array[] = { E(r, s), E(r, v), E(s, w), E(w, r), E(w, t),
  45. E(w, x), E(x, t), E(t, u), E(x, y), E(u, y)
  46. };
  47. // Create the graph object
  48. const int n_edges = sizeof(edge_array) / sizeof(E);
  49. #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
  50. // VC++ has trouble with the edge iterator constructor
  51. graph_t g;
  52. std::vector<graph_traits<graph_t>::vertex_descriptor> verts;
  53. for (std::size_t i = 0; i < N; ++i)
  54. verts.push_back(add_vertex(g));
  55. for (std::size_t j = 0; j < n_edges; ++j)
  56. add_edge(verts[edge_array[j].first], verts[edge_array[j].second], g);
  57. #else
  58. typedef graph_traits<graph_t>::vertices_size_type v_size_t;
  59. graph_t g(edge_array, edge_array + n_edges, v_size_t(N));
  60. #endif
  61. // Typedefs
  62. typedef graph_traits<graph_t>::vertices_size_type Size;
  63. Size time = 0;
  64. typedef property_map<graph_t, std::size_t VertexProps::*>::type dtime_map_t;
  65. dtime_map_t dtime_map = get(&VertexProps::discover_time, g);
  66. bfs_time_visitor < dtime_map_t > vis(dtime_map, time);
  67. breadth_first_search(g, vertex(s, g), color_map(get(&VertexProps::color, g)).
  68. visitor(vis));
  69. // a vector to hold the discover time property for each vertex
  70. std::vector < Size > dtime(num_vertices(g));
  71. typedef
  72. iterator_property_map<std::vector<Size>::iterator,
  73. property_map<graph_t, unsigned int VertexProps::*>::type>
  74. dtime_pm_type;
  75. graph_traits<graph_t>::vertex_iterator vi, vi_end;
  76. std::size_t c = 0;
  77. for (boost::tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi, ++c) {
  78. dtime[c] = dtime_map[*vi];
  79. put(&VertexProps::index, g, *vi, c);
  80. }
  81. dtime_pm_type dtime_pm(dtime.begin(), get(&VertexProps::index, g));
  82. // Use std::sort to order the vertices by their discover time
  83. std::vector<graph_traits<graph_t>::vertices_size_type > discover_order(N);
  84. integer_range < int >range(0, N);
  85. std::copy(range.begin(), range.end(), discover_order.begin());
  86. std::sort(discover_order.begin(), discover_order.end(),
  87. make_indirect_cmp(
  88. std::less<Size>(),
  89. make_iterator_property_map(
  90. dtime.begin(),
  91. typed_identity_property_map<std::size_t>())));
  92. std::cout << "order of discovery: ";
  93. for (int i = 0; i < N; ++i)
  94. std::cout << name[discover_order[i]] << " ";
  95. std::cout << std::endl;
  96. return EXIT_SUCCESS;
  97. }