biconnected_components.hpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. // Copyright (c) Jeremy Siek 2001
  2. // Copyright (c) Douglas Gregor 2004
  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. // NOTE: this final is generated by libs/graph/doc/biconnected_components.w
  8. #ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
  9. #define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP
  10. #include <stack>
  11. #include <vector>
  12. #include <algorithm> // for std::min and std::max
  13. #include <boost/config.hpp>
  14. #include <boost/limits.hpp>
  15. #include <boost/graph/graph_traits.hpp>
  16. #include <boost/graph/graph_concepts.hpp>
  17. #include <boost/property_map/property_map.hpp>
  18. #include <boost/graph/depth_first_search.hpp>
  19. #include <boost/graph/graph_utility.hpp>
  20. #include <boost/concept/assert.hpp>
  21. #include <boost/assert.hpp>
  22. namespace boost
  23. {
  24. namespace detail
  25. {
  26. template < typename ComponentMap, typename DiscoverTimeMap,
  27. typename LowPointMap, typename PredecessorMap, typename OutputIterator,
  28. typename Stack, typename ArticulationVector, typename IndexMap,
  29. typename DFSVisitor >
  30. struct biconnected_components_visitor : public dfs_visitor<>
  31. {
  32. biconnected_components_visitor(ComponentMap comp, std::size_t& c,
  33. std::size_t& children_of_root, DiscoverTimeMap dtm,
  34. std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred,
  35. OutputIterator out, Stack& S,
  36. ArticulationVector& is_articulation_point, IndexMap index_map,
  37. DFSVisitor vis)
  38. : comp(comp)
  39. , c(c)
  40. , children_of_root(children_of_root)
  41. , dtm(dtm)
  42. , dfs_time(dfs_time)
  43. , lowpt(lowpt)
  44. , pred(pred)
  45. , out(out)
  46. , S(S)
  47. , is_articulation_point(is_articulation_point)
  48. , index_map(index_map)
  49. , vis(vis)
  50. {
  51. }
  52. template < typename Vertex, typename Graph >
  53. void initialize_vertex(const Vertex& u, Graph& g)
  54. {
  55. put(pred, u, u);
  56. vis.initialize_vertex(u, g);
  57. }
  58. template < typename Vertex, typename Graph >
  59. void start_vertex(const Vertex& u, Graph& g)
  60. {
  61. children_of_root = 0;
  62. vis.start_vertex(u, g);
  63. }
  64. template < typename Vertex, typename Graph >
  65. void discover_vertex(const Vertex& u, Graph& g)
  66. {
  67. put(dtm, u, ++dfs_time);
  68. put(lowpt, u, get(dtm, u));
  69. vis.discover_vertex(u, g);
  70. }
  71. template < typename Edge, typename Graph >
  72. void examine_edge(const Edge& e, Graph& g)
  73. {
  74. vis.examine_edge(e, g);
  75. }
  76. template < typename Edge, typename Graph >
  77. void tree_edge(const Edge& e, Graph& g)
  78. {
  79. typename boost::graph_traits< Graph >::vertex_descriptor src
  80. = source(e, g);
  81. typename boost::graph_traits< Graph >::vertex_descriptor tgt
  82. = target(e, g);
  83. S.push(e);
  84. put(pred, tgt, src);
  85. if (get(pred, src) == src)
  86. {
  87. ++children_of_root;
  88. }
  89. vis.tree_edge(e, g);
  90. }
  91. template < typename Edge, typename Graph >
  92. void back_edge(const Edge& e, Graph& g)
  93. {
  94. BOOST_USING_STD_MIN();
  95. typename boost::graph_traits< Graph >::vertex_descriptor src
  96. = source(e, g);
  97. typename boost::graph_traits< Graph >::vertex_descriptor tgt
  98. = target(e, g);
  99. if (tgt != get(pred, src))
  100. {
  101. S.push(e);
  102. put(lowpt, src,
  103. min BOOST_PREVENT_MACRO_SUBSTITUTION(
  104. get(lowpt, src), get(dtm, tgt)));
  105. }
  106. vis.back_edge(e, g);
  107. }
  108. template < typename Edge, typename Graph >
  109. void forward_or_cross_edge(const Edge& e, Graph& g)
  110. {
  111. vis.forward_or_cross_edge(e, g);
  112. }
  113. template < typename Vertex, typename Graph >
  114. void finish_vertex(const Vertex& u, Graph& g)
  115. {
  116. BOOST_USING_STD_MIN();
  117. Vertex parent = get(pred, u);
  118. if (parent == u)
  119. { // Root of tree is special
  120. is_articulation_point[get(index_map, u)]
  121. = (children_of_root > 1);
  122. }
  123. else
  124. {
  125. put(lowpt, parent,
  126. min BOOST_PREVENT_MACRO_SUBSTITUTION(
  127. get(lowpt, parent), get(lowpt, u)));
  128. if (get(lowpt, u) >= get(dtm, parent))
  129. {
  130. is_articulation_point[get(index_map, parent)] = true;
  131. while (get(dtm, source(S.top(), g)) >= get(dtm, u))
  132. {
  133. put(comp, S.top(), c);
  134. S.pop();
  135. }
  136. BOOST_ASSERT(source(S.top(), g) == parent);
  137. BOOST_ASSERT(target(S.top(), g) == u);
  138. put(comp, S.top(), c);
  139. S.pop();
  140. ++c;
  141. }
  142. }
  143. if (is_articulation_point[get(index_map, u)])
  144. {
  145. *out++ = u;
  146. }
  147. vis.finish_vertex(u, g);
  148. }
  149. ComponentMap comp;
  150. std::size_t& c;
  151. std::size_t& children_of_root;
  152. DiscoverTimeMap dtm;
  153. std::size_t& dfs_time;
  154. LowPointMap lowpt;
  155. PredecessorMap pred;
  156. OutputIterator out;
  157. Stack& S;
  158. ArticulationVector& is_articulation_point;
  159. IndexMap index_map;
  160. DFSVisitor vis;
  161. };
  162. template < typename Graph, typename ComponentMap, typename OutputIterator,
  163. typename VertexIndexMap, typename DiscoverTimeMap, typename LowPointMap,
  164. typename PredecessorMap, typename DFSVisitor >
  165. std::pair< std::size_t, OutputIterator > biconnected_components_impl(
  166. const Graph& g, ComponentMap comp, OutputIterator out,
  167. VertexIndexMap index_map, DiscoverTimeMap dtm, LowPointMap lowpt,
  168. PredecessorMap pred, DFSVisitor dfs_vis)
  169. {
  170. typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
  171. typedef typename graph_traits< Graph >::edge_descriptor edge_t;
  172. BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
  173. BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
  174. BOOST_CONCEPT_ASSERT(
  175. (WritablePropertyMapConcept< ComponentMap, edge_t >));
  176. BOOST_CONCEPT_ASSERT(
  177. (ReadWritePropertyMapConcept< DiscoverTimeMap, vertex_t >));
  178. BOOST_CONCEPT_ASSERT(
  179. (ReadWritePropertyMapConcept< LowPointMap, vertex_t >));
  180. BOOST_CONCEPT_ASSERT(
  181. (ReadWritePropertyMapConcept< PredecessorMap, vertex_t >));
  182. std::size_t num_components = 0;
  183. std::size_t children_of_root;
  184. std::size_t dfs_time = 0;
  185. std::stack< edge_t > S;
  186. std::vector< char > is_articulation_point(num_vertices(g));
  187. biconnected_components_visitor< ComponentMap, DiscoverTimeMap,
  188. LowPointMap, PredecessorMap, OutputIterator, std::stack< edge_t >,
  189. std::vector< char >, VertexIndexMap, DFSVisitor >
  190. vis(comp, num_components, children_of_root, dtm, dfs_time, lowpt,
  191. pred, out, S, is_articulation_point, index_map, dfs_vis);
  192. depth_first_search(g, visitor(vis).vertex_index_map(index_map));
  193. return std::pair< std::size_t, OutputIterator >(
  194. num_components, vis.out);
  195. }
  196. template < typename PredecessorMap > struct bicomp_dispatch3
  197. {
  198. template < typename Graph, typename ComponentMap,
  199. typename OutputIterator, typename VertexIndexMap,
  200. typename DiscoverTimeMap, typename LowPointMap, class P, class T,
  201. class R >
  202. static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
  203. ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
  204. DiscoverTimeMap dtm, LowPointMap lowpt,
  205. const bgl_named_params< P, T, R >& params, PredecessorMap pred)
  206. {
  207. return biconnected_components_impl(g, comp, out, index_map, dtm,
  208. lowpt, pred,
  209. choose_param(get_param(params, graph_visitor),
  210. make_dfs_visitor(null_visitor())));
  211. }
  212. };
  213. template <> struct bicomp_dispatch3< param_not_found >
  214. {
  215. template < typename Graph, typename ComponentMap,
  216. typename OutputIterator, typename VertexIndexMap,
  217. typename DiscoverTimeMap, typename LowPointMap, class P, class T,
  218. class R >
  219. static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
  220. ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
  221. DiscoverTimeMap dtm, LowPointMap lowpt,
  222. const bgl_named_params< P, T, R >& params, param_not_found)
  223. {
  224. typedef typename graph_traits< Graph >::vertex_descriptor vertex_t;
  225. std::vector< vertex_t > pred(num_vertices(g));
  226. vertex_t vert = graph_traits< Graph >::null_vertex();
  227. return biconnected_components_impl(g, comp, out, index_map, dtm,
  228. lowpt,
  229. make_iterator_property_map(pred.begin(), index_map, vert),
  230. choose_param(get_param(params, graph_visitor),
  231. make_dfs_visitor(null_visitor())));
  232. }
  233. };
  234. template < typename LowPointMap > struct bicomp_dispatch2
  235. {
  236. template < typename Graph, typename ComponentMap,
  237. typename OutputIterator, typename VertexIndexMap,
  238. typename DiscoverTimeMap, typename P, typename T, typename R >
  239. static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
  240. ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
  241. DiscoverTimeMap dtm, const bgl_named_params< P, T, R >& params,
  242. LowPointMap lowpt)
  243. {
  244. typedef typename get_param_type< vertex_predecessor_t,
  245. bgl_named_params< P, T, R > >::type dispatch_type;
  246. return bicomp_dispatch3< dispatch_type >::apply(g, comp, out,
  247. index_map, dtm, lowpt, params,
  248. get_param(params, vertex_predecessor));
  249. }
  250. };
  251. template <> struct bicomp_dispatch2< param_not_found >
  252. {
  253. template < typename Graph, typename ComponentMap,
  254. typename OutputIterator, typename VertexIndexMap,
  255. typename DiscoverTimeMap, typename P, typename T, typename R >
  256. static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
  257. ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
  258. DiscoverTimeMap dtm, const bgl_named_params< P, T, R >& params,
  259. param_not_found)
  260. {
  261. typedef typename graph_traits< Graph >::vertices_size_type
  262. vertices_size_type;
  263. std::vector< vertices_size_type > lowpt(num_vertices(g));
  264. vertices_size_type vst(0);
  265. typedef typename get_param_type< vertex_predecessor_t,
  266. bgl_named_params< P, T, R > >::type dispatch_type;
  267. return bicomp_dispatch3< dispatch_type >::apply(g, comp, out,
  268. index_map, dtm,
  269. make_iterator_property_map(lowpt.begin(), index_map, vst),
  270. params, get_param(params, vertex_predecessor));
  271. }
  272. };
  273. template < typename DiscoverTimeMap > struct bicomp_dispatch1
  274. {
  275. template < typename Graph, typename ComponentMap,
  276. typename OutputIterator, typename VertexIndexMap, class P, class T,
  277. class R >
  278. static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
  279. ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
  280. const bgl_named_params< P, T, R >& params, DiscoverTimeMap dtm)
  281. {
  282. typedef typename get_param_type< vertex_lowpoint_t,
  283. bgl_named_params< P, T, R > >::type dispatch_type;
  284. return bicomp_dispatch2< dispatch_type >::apply(g, comp, out,
  285. index_map, dtm, params, get_param(params, vertex_lowpoint));
  286. }
  287. };
  288. template <> struct bicomp_dispatch1< param_not_found >
  289. {
  290. template < typename Graph, typename ComponentMap,
  291. typename OutputIterator, typename VertexIndexMap, class P, class T,
  292. class R >
  293. static std::pair< std::size_t, OutputIterator > apply(const Graph& g,
  294. ComponentMap comp, OutputIterator out, VertexIndexMap index_map,
  295. const bgl_named_params< P, T, R >& params, param_not_found)
  296. {
  297. typedef typename graph_traits< Graph >::vertices_size_type
  298. vertices_size_type;
  299. std::vector< vertices_size_type > discover_time(num_vertices(g));
  300. vertices_size_type vst(0);
  301. typedef typename get_param_type< vertex_lowpoint_t,
  302. bgl_named_params< P, T, R > >::type dispatch_type;
  303. return bicomp_dispatch2< dispatch_type >::apply(g, comp, out,
  304. index_map,
  305. make_iterator_property_map(
  306. discover_time.begin(), index_map, vst),
  307. params, get_param(params, vertex_lowpoint));
  308. }
  309. };
  310. }
  311. template < typename Graph, typename ComponentMap, typename OutputIterator,
  312. typename DiscoverTimeMap, typename LowPointMap >
  313. std::pair< std::size_t, OutputIterator > biconnected_components(const Graph& g,
  314. ComponentMap comp, OutputIterator out, DiscoverTimeMap dtm,
  315. LowPointMap lowpt)
  316. {
  317. typedef param_not_found dispatch_type;
  318. return detail::bicomp_dispatch3< dispatch_type >::apply(g, comp, out,
  319. get(vertex_index, g), dtm, lowpt,
  320. bgl_named_params< int, buffer_param_t >(0), param_not_found());
  321. }
  322. template < typename Graph, typename ComponentMap, typename OutputIterator,
  323. typename P, typename T, typename R >
  324. std::pair< std::size_t, OutputIterator > biconnected_components(const Graph& g,
  325. ComponentMap comp, OutputIterator out,
  326. const bgl_named_params< P, T, R >& params)
  327. {
  328. typedef typename get_param_type< vertex_discover_time_t,
  329. bgl_named_params< P, T, R > >::type dispatch_type;
  330. return detail::bicomp_dispatch1< dispatch_type >::apply(g, comp, out,
  331. choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
  332. params, get_param(params, vertex_discover_time));
  333. }
  334. template < typename Graph, typename ComponentMap, typename OutputIterator >
  335. std::pair< std::size_t, OutputIterator > biconnected_components(
  336. const Graph& g, ComponentMap comp, OutputIterator out)
  337. {
  338. return biconnected_components(
  339. g, comp, out, bgl_named_params< int, buffer_param_t >(0));
  340. }
  341. namespace graph_detail
  342. {
  343. struct dummy_output_iterator
  344. {
  345. typedef std::output_iterator_tag iterator_category;
  346. typedef void value_type;
  347. typedef void pointer;
  348. typedef void difference_type;
  349. struct reference
  350. {
  351. template < typename T > reference& operator=(const T&)
  352. {
  353. return *this;
  354. }
  355. };
  356. reference operator*() const { return reference(); }
  357. dummy_output_iterator& operator++() { return *this; }
  358. dummy_output_iterator operator++(int) { return *this; }
  359. };
  360. } // end namespace graph_detail
  361. template < typename Graph, typename ComponentMap, typename P, typename T,
  362. typename R >
  363. std::size_t biconnected_components(const Graph& g, ComponentMap comp,
  364. const bgl_named_params< P, T, R >& params)
  365. {
  366. return biconnected_components(
  367. g, comp, graph_detail::dummy_output_iterator(), params)
  368. .first;
  369. }
  370. template < typename Graph, typename ComponentMap >
  371. std::size_t biconnected_components(const Graph& g, ComponentMap comp)
  372. {
  373. return biconnected_components(
  374. g, comp, graph_detail::dummy_output_iterator())
  375. .first;
  376. }
  377. template < typename Graph, typename OutputIterator, typename P, typename T,
  378. typename R >
  379. OutputIterator articulation_points(const Graph& g, OutputIterator out,
  380. const bgl_named_params< P, T, R >& params)
  381. {
  382. return biconnected_components(g, dummy_property_map(), out, params).second;
  383. }
  384. template < typename Graph, typename OutputIterator >
  385. OutputIterator articulation_points(const Graph& g, OutputIterator out)
  386. {
  387. return biconnected_components(g, dummy_property_map(), out,
  388. bgl_named_params< int, buffer_param_t >(0))
  389. .second;
  390. }
  391. } // namespace boost
  392. #endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */