hawick_circuits.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // Copyright Louis Dionne 2013
  2. // Use, modification and distribution is subject to the Boost Software
  3. // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
  4. // at http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/assert.hpp>
  6. #include <boost/graph/directed_graph.hpp>
  7. #include <boost/graph/graph_traits.hpp>
  8. #include <boost/graph/hawick_circuits.hpp>
  9. #include <boost/lexical_cast.hpp>
  10. #include <boost/next_prior.hpp>
  11. #include <boost/property_map/property_map.hpp>
  12. #include <cstdlib>
  13. #include <iostream>
  14. #include <iterator>
  15. #include <map>
  16. template <typename OutputStream>
  17. struct cycle_printer
  18. {
  19. cycle_printer(OutputStream& stream)
  20. : os(stream)
  21. { }
  22. template <typename Path, typename Graph>
  23. void cycle(Path const& p, Graph const& g)
  24. {
  25. if (p.empty())
  26. return;
  27. // Get the property map containing the vertex indices
  28. // so we can print them.
  29. typedef typename boost::property_map<
  30. Graph, boost::vertex_index_t
  31. >::const_type IndexMap;
  32. IndexMap indices = get(boost::vertex_index, g);
  33. // Iterate over path printing each vertex that forms the cycle.
  34. typename Path::const_iterator i, before_end = boost::prior(p.end());
  35. for (i = p.begin(); i != before_end; ++i) {
  36. os << get(indices, *i) << " ";
  37. }
  38. os << get(indices, *i) << '\n';
  39. }
  40. OutputStream& os;
  41. };
  42. // VertexPairIterator is an iterator over pairs of whitespace separated
  43. // vertices `u` and `v` representing a directed edge from `u` to `v`.
  44. template <typename Graph, typename VertexPairIterator>
  45. void build_graph(Graph& graph, unsigned int const nvertices,
  46. VertexPairIterator first, VertexPairIterator last) {
  47. typedef boost::graph_traits<Graph> Traits;
  48. typedef typename Traits::vertex_descriptor vertex_descriptor;
  49. std::map<unsigned int, vertex_descriptor> vertices;
  50. for (unsigned int i = 0; i < nvertices; ++i)
  51. vertices[i] = add_vertex(graph);
  52. for (; first != last; ++first) {
  53. unsigned int u = *first++;
  54. BOOST_ASSERT_MSG(first != last,
  55. "there is a lonely vertex at the end of the edge list");
  56. unsigned int v = *first;
  57. BOOST_ASSERT_MSG(vertices.count(u) == 1 && vertices.count(v) == 1,
  58. "specified a vertex over the number of vertices in the graph");
  59. add_edge(vertices[u], vertices[v], graph);
  60. }
  61. BOOST_ASSERT(num_vertices(graph) == nvertices);
  62. }
  63. int main(int argc, char const* argv[]) {
  64. if (argc < 2) {
  65. std::cout << "usage: " << argv[0] << " num_vertices < input\n";
  66. return EXIT_FAILURE;
  67. }
  68. unsigned int num_vertices = boost::lexical_cast<unsigned int>(argv[1]);
  69. std::istream_iterator<unsigned int> first_vertex(std::cin), last_vertex;
  70. boost::directed_graph<> graph;
  71. build_graph(graph, num_vertices, first_vertex, last_vertex);
  72. cycle_printer<std::ostream> visitor(std::cout);
  73. boost::hawick_circuits(graph, visitor);
  74. return EXIT_SUCCESS;
  75. }