dfs.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //=======================================================================
  2. // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
  3. // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
  4. //
  5. // Distributed under the Boost Software License, Version 1.0. (See
  6. // accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //=======================================================================
  9. #include <boost/config.hpp>
  10. #include <assert.h>
  11. #include <iostream>
  12. #include <vector>
  13. #include <algorithm>
  14. #include <utility>
  15. #include <boost/graph/adjacency_list.hpp>
  16. #include <boost/graph/depth_first_search.hpp>
  17. #include <boost/graph/visitors.hpp>
  18. /*
  19. This calculates the discover finishing time.
  20. Sample Output
  21. Tree edge: 0 --> 2
  22. Tree edge: 2 --> 1
  23. Back edge: 1 --> 1
  24. Finish edge: 1 --> 1
  25. Tree edge: 1 --> 3
  26. Back edge: 3 --> 1
  27. Finish edge: 3 --> 1
  28. Tree edge: 3 --> 4
  29. Back edge: 4 --> 0
  30. Finish edge: 4 --> 0
  31. Back edge: 4 --> 1
  32. Finish edge: 4 --> 1
  33. Forward or cross edge: 2 --> 3
  34. Finish edge: 2 --> 3
  35. Finish edge: 0 --> 2
  36. 1 10
  37. 3 8
  38. 2 9
  39. 4 7
  40. 5 6
  41. */
  42. using namespace boost;
  43. using namespace std;
  44. template <class VisitorList>
  45. struct edge_categorizer : public dfs_visitor<VisitorList> {
  46. typedef dfs_visitor<VisitorList> Base;
  47. edge_categorizer(const VisitorList& v = null_visitor()) : Base(v) { }
  48. template <class Edge, class Graph>
  49. void tree_edge(Edge e, Graph& G) {
  50. cout << "Tree edge: " << source(e, G) <<
  51. " --> " << target(e, G) << endl;
  52. Base::tree_edge(e, G);
  53. }
  54. template <class Edge, class Graph>
  55. void back_edge(Edge e, Graph& G) {
  56. cout << "Back edge: " << source(e, G)
  57. << " --> " << target(e, G) << endl;
  58. Base::back_edge(e, G);
  59. }
  60. template <class Edge, class Graph>
  61. void forward_or_cross_edge(Edge e, Graph& G) {
  62. cout << "Forward or cross edge: " << source(e, G)
  63. << " --> " << target(e, G) << endl;
  64. Base::forward_or_cross_edge(e, G);
  65. }
  66. template <class Edge, class Graph>
  67. void finish_edge(Edge e, Graph& G) {
  68. cout << "Finish edge: " << source(e, G) <<
  69. " --> " << target(e, G) << endl;
  70. Base::finish_edge(e, G);
  71. }
  72. };
  73. template <class VisitorList>
  74. edge_categorizer<VisitorList>
  75. categorize_edges(const VisitorList& v) {
  76. return edge_categorizer<VisitorList>(v);
  77. }
  78. int
  79. main(int , char* [])
  80. {
  81. using namespace boost;
  82. typedef adjacency_list<> Graph;
  83. Graph G(5);
  84. add_edge(0, 2, G);
  85. add_edge(1, 1, G);
  86. add_edge(1, 3, G);
  87. add_edge(2, 1, G);
  88. add_edge(2, 3, G);
  89. add_edge(3, 1, G);
  90. add_edge(3, 4, G);
  91. add_edge(4, 0, G);
  92. add_edge(4, 1, G);
  93. typedef graph_traits<Graph>::vertices_size_type size_type;
  94. std::vector<size_type> d(num_vertices(G));
  95. std::vector<size_type> f(num_vertices(G));
  96. int t = 0;
  97. depth_first_search(G, visitor(categorize_edges(
  98. make_pair(stamp_times(&d[0], t, on_discover_vertex()),
  99. stamp_times(&f[0], t, on_finish_vertex())))));
  100. std::vector<size_type>::iterator i, j;
  101. for (i = d.begin(), j = f.begin(); i != d.end(); ++i, ++j)
  102. cout << *i << " " << *j << endl;
  103. return 0;
  104. }