sl@0: // Copyright (c) Jeremy Siek 2001 sl@0: // Copyright (c) Douglas Gregor 2004 sl@0: // sl@0: // Distributed under the Boost Software License, Version 1.0. (See sl@0: // accompanying file LICENSE_1_0.txt or copy at sl@0: // http://www.boost.org/LICENSE_1_0.txt) sl@0: sl@0: // NOTE: this final is generated by libs/graph/doc/biconnected_components.w sl@0: sl@0: #ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP sl@0: #define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP sl@0: sl@0: #include sl@0: #include sl@0: #include // for std::min and std::max sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: namespace boost sl@0: { sl@0: namespace detail sl@0: { sl@0: template sl@0: struct biconnected_components_visitor : public dfs_visitor<> sl@0: { sl@0: biconnected_components_visitor sl@0: (ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm, sl@0: std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred, sl@0: OutputIterator out, Stack& S, DFSVisitor vis) sl@0: : comp(comp), c(c), dtm(dtm), dfs_time(dfs_time), lowpt(lowpt), sl@0: pred(pred), out(out), S(S), vis(vis) { } sl@0: sl@0: template sl@0: void initialize_vertex(const Vertex& u, Graph& g) sl@0: { sl@0: vis.initialize_vertex(u, g); sl@0: } sl@0: sl@0: template sl@0: void start_vertex(const Vertex& u, Graph& g) sl@0: { sl@0: put(pred, u, u); sl@0: vis.start_vertex(u, g); sl@0: } sl@0: sl@0: template sl@0: void discover_vertex(const Vertex& u, Graph& g) sl@0: { sl@0: put(dtm, u, ++dfs_time); sl@0: put(lowpt, u, get(dtm, u)); sl@0: vis.discover_vertex(u, g); sl@0: } sl@0: sl@0: template sl@0: void examine_edge(const Edge& e, Graph& g) sl@0: { sl@0: vis.examine_edge(e, g); sl@0: } sl@0: sl@0: template sl@0: void tree_edge(const Edge& e, Graph& g) sl@0: { sl@0: S.push(e); sl@0: put(pred, target(e, g), source(e, g)); sl@0: vis.tree_edge(e, g); sl@0: } sl@0: sl@0: template sl@0: void back_edge(const Edge& e, Graph& g) sl@0: { sl@0: BOOST_USING_STD_MIN(); sl@0: sl@0: if ( target(e, g) != get(pred, source(e, g)) ) { sl@0: S.push(e); sl@0: put(lowpt, source(e, g), sl@0: min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, source(e, g)), sl@0: get(dtm, target(e, g)))); sl@0: vis.back_edge(e, g); sl@0: } sl@0: } sl@0: sl@0: template sl@0: void forward_or_cross_edge(const Edge& e, Graph& g) sl@0: { sl@0: vis.forward_or_cross_edge(e, g); sl@0: } sl@0: sl@0: template sl@0: void finish_vertex(const Vertex& u, Graph& g) sl@0: { sl@0: BOOST_USING_STD_MIN(); sl@0: Vertex parent = get(pred, u); sl@0: const std::size_t dtm_of_dubious_parent = get(dtm, parent); sl@0: bool is_art_point = false; sl@0: if ( dtm_of_dubious_parent > get(dtm, u) ) { sl@0: parent = get(pred, parent); sl@0: is_art_point = true; sl@0: put(pred, get(pred, u), u); sl@0: put(pred, u, parent); sl@0: } sl@0: sl@0: if ( parent == u ) { // at top sl@0: if ( get(dtm, u) + 1 == dtm_of_dubious_parent ) sl@0: is_art_point = false; sl@0: } else { sl@0: put(lowpt, parent, sl@0: min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent), sl@0: get(lowpt, u))); sl@0: sl@0: if (get(lowpt, u) >= get(dtm, parent)) { sl@0: if ( get(dtm, parent) > get(dtm, get(pred, parent)) ) { sl@0: put(pred, u, get(pred, parent)); sl@0: put(pred, parent, u); sl@0: } sl@0: sl@0: while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) { sl@0: put(comp, S.top(), c); sl@0: S.pop(); sl@0: } sl@0: put(comp, S.top(), c); sl@0: S.pop(); sl@0: ++c; sl@0: if ( S.empty() ) { sl@0: put(pred, u, parent); sl@0: put(pred, parent, u); sl@0: } sl@0: } sl@0: } sl@0: if ( is_art_point ) sl@0: *out++ = u; sl@0: vis.finish_vertex(u, g); sl@0: } sl@0: sl@0: ComponentMap comp; sl@0: std::size_t& c; sl@0: DiscoverTimeMap dtm; sl@0: std::size_t& dfs_time; sl@0: LowPointMap lowpt; sl@0: PredecessorMap pred; sl@0: OutputIterator out; sl@0: Stack& S; sl@0: DFSVisitor vis; sl@0: }; sl@0: sl@0: template sl@0: std::pair sl@0: biconnected_components_impl(const Graph & g, ComponentMap comp, sl@0: OutputIterator out, VertexIndexMap index_map, DiscoverTimeMap dtm, sl@0: LowPointMap lowpt, PredecessorMap pred, DFSVisitor dfs_vis) sl@0: { sl@0: typedef typename graph_traits::vertex_descriptor vertex_t; sl@0: typedef typename graph_traits::edge_descriptor edge_t; sl@0: function_requires >(); sl@0: function_requires >(); sl@0: function_requires >(); sl@0: function_requires >(); sl@0: function_requires >(); sl@0: function_requires >(); sl@0: sl@0: std::size_t num_components = 0; sl@0: std::size_t dfs_time = 0; sl@0: std::stack S; sl@0: sl@0: biconnected_components_visitor, sl@0: DFSVisitor> sl@0: vis(comp, num_components, dtm, dfs_time, lowpt, pred, out, sl@0: S, dfs_vis); sl@0: sl@0: depth_first_search(g, visitor(vis).vertex_index_map(index_map)); sl@0: sl@0: return std::pair(num_components, vis.out); sl@0: } sl@0: sl@0: template sl@0: struct bicomp_dispatch3 sl@0: { sl@0: template sl@0: static std::pair apply (const Graph & g, sl@0: ComponentMap comp, OutputIterator out, VertexIndexMap index_map, sl@0: DiscoverTimeMap dtm, LowPointMap lowpt, sl@0: const bgl_named_params& params, PredecessorMap pred) sl@0: { sl@0: return biconnected_components_impl sl@0: (g, comp, out, index_map, dtm, lowpt, pred, sl@0: choose_param(get_param(params, graph_visitor), sl@0: make_dfs_visitor(null_visitor()))); sl@0: } sl@0: }; sl@0: sl@0: template <> sl@0: struct bicomp_dispatch3 sl@0: { sl@0: template sl@0: static std::pair apply (const Graph & g, sl@0: ComponentMap comp, OutputIterator out, VertexIndexMap index_map, sl@0: DiscoverTimeMap dtm, LowPointMap lowpt, sl@0: const bgl_named_params& params, sl@0: error_property_not_found) sl@0: { sl@0: typedef typename graph_traits::vertex_descriptor vertex_t; sl@0: std::vector pred(num_vertices(g)); sl@0: vertex_t vert = graph_traits::null_vertex(); sl@0: sl@0: return biconnected_components_impl sl@0: (g, comp, out, index_map, dtm, lowpt, sl@0: make_iterator_property_map(pred.begin(), index_map, vert), sl@0: choose_param(get_param(params, graph_visitor), sl@0: make_dfs_visitor(null_visitor()))); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: struct bicomp_dispatch2 sl@0: { sl@0: template sl@0: static std::pair apply (const Graph& g, sl@0: ComponentMap comp, OutputIterator out, VertexIndexMap index_map, sl@0: DiscoverTimeMap dtm, const bgl_named_params& params, sl@0: LowPointMap lowpt) sl@0: { sl@0: typedef typename property_value< bgl_named_params, sl@0: vertex_predecessor_t>::type dispatch_type; sl@0: sl@0: return bicomp_dispatch3::apply sl@0: (g, comp, out, index_map, dtm, lowpt, params, sl@0: get_param(params, vertex_predecessor)); sl@0: } sl@0: }; sl@0: sl@0: sl@0: template <> sl@0: struct bicomp_dispatch2 sl@0: { sl@0: template sl@0: static std::pair apply (const Graph& g, sl@0: ComponentMap comp, OutputIterator out, VertexIndexMap index_map, sl@0: DiscoverTimeMap dtm, const bgl_named_params& params, sl@0: error_property_not_found) sl@0: { sl@0: typedef typename graph_traits::vertices_size_type sl@0: vertices_size_type; sl@0: std::vector lowpt(num_vertices(g)); sl@0: vertices_size_type vst(0); sl@0: sl@0: typedef typename property_value< bgl_named_params, sl@0: vertex_predecessor_t>::type dispatch_type; sl@0: sl@0: return bicomp_dispatch3::apply sl@0: (g, comp, out, index_map, dtm, sl@0: make_iterator_property_map(lowpt.begin(), index_map, vst), sl@0: params, get_param(params, vertex_predecessor)); sl@0: } sl@0: }; sl@0: sl@0: template sl@0: struct bicomp_dispatch1 sl@0: { sl@0: template sl@0: static std::pair apply(const Graph& g, sl@0: ComponentMap comp, OutputIterator out, VertexIndexMap index_map, sl@0: const bgl_named_params& params, DiscoverTimeMap dtm) sl@0: { sl@0: typedef typename property_value< bgl_named_params, sl@0: vertex_lowpoint_t>::type dispatch_type; sl@0: sl@0: return bicomp_dispatch2::apply sl@0: (g, comp, out, index_map, dtm, params, sl@0: get_param(params, vertex_lowpoint)); sl@0: } sl@0: }; sl@0: sl@0: template <> sl@0: struct bicomp_dispatch1 sl@0: { sl@0: template sl@0: static std::pair apply(const Graph& g, sl@0: ComponentMap comp, OutputIterator out, VertexIndexMap index_map, sl@0: const bgl_named_params& params, error_property_not_found) sl@0: { sl@0: typedef typename graph_traits::vertices_size_type sl@0: vertices_size_type; sl@0: std::vector discover_time(num_vertices(g)); sl@0: vertices_size_type vst(0); sl@0: sl@0: typedef typename property_value< bgl_named_params, sl@0: vertex_lowpoint_t>::type dispatch_type; sl@0: sl@0: return bicomp_dispatch2::apply sl@0: (g, comp, out, index_map, sl@0: make_iterator_property_map(discover_time.begin(), index_map, vst), sl@0: params, get_param(params, vertex_lowpoint)); sl@0: } sl@0: }; sl@0: sl@0: } sl@0: sl@0: template sl@0: std::pair sl@0: biconnected_components(const Graph& g, ComponentMap comp, sl@0: OutputIterator out, DiscoverTimeMap dtm, LowPointMap lowpt) sl@0: { sl@0: typedef detail::error_property_not_found dispatch_type; sl@0: sl@0: return detail::bicomp_dispatch3::apply sl@0: (g, comp, out, sl@0: get(vertex_index, g), sl@0: dtm, lowpt, sl@0: bgl_named_params(0), sl@0: detail::error_property_not_found()); sl@0: } sl@0: sl@0: template sl@0: std::pair sl@0: biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out, sl@0: const bgl_named_params& params) sl@0: { sl@0: typedef typename property_value< bgl_named_params, sl@0: vertex_discover_time_t>::type dispatch_type; sl@0: sl@0: return detail::bicomp_dispatch1::apply(g, comp, out, sl@0: choose_const_pmap(get_param(params, vertex_index), g, vertex_index), sl@0: params, get_param(params, vertex_discover_time)); sl@0: } sl@0: sl@0: template < typename Graph, typename ComponentMap, typename OutputIterator> sl@0: std::pair sl@0: biconnected_components(const Graph& g, ComponentMap comp, OutputIterator out) sl@0: { sl@0: return biconnected_components(g, comp, out, sl@0: bgl_named_params(0)); sl@0: } sl@0: sl@0: namespace graph_detail { sl@0: struct dummy_output_iterator sl@0: { sl@0: typedef std::output_iterator_tag iterator_category; sl@0: typedef void value_type; sl@0: typedef void pointer; sl@0: typedef void difference_type; sl@0: sl@0: struct reference { sl@0: template sl@0: reference& operator=(const T&) { return *this; } sl@0: }; sl@0: sl@0: reference operator*() const { return reference(); } sl@0: dummy_output_iterator& operator++() { return *this; } sl@0: dummy_output_iterator operator++(int) { return *this; } sl@0: }; sl@0: } // end namespace graph_detail sl@0: sl@0: template sl@0: std::size_t sl@0: biconnected_components(const Graph& g, ComponentMap comp, sl@0: const bgl_named_params& params) sl@0: { sl@0: return biconnected_components(g, comp, sl@0: graph_detail::dummy_output_iterator(), params).first; sl@0: } sl@0: sl@0: template sl@0: std::size_t sl@0: biconnected_components(const Graph& g, ComponentMap comp) sl@0: { sl@0: return biconnected_components(g, comp, sl@0: graph_detail::dummy_output_iterator()).first; sl@0: } sl@0: sl@0: template sl@0: OutputIterator sl@0: articulation_points(const Graph& g, OutputIterator out, sl@0: const bgl_named_params& params) sl@0: { sl@0: return biconnected_components(g, dummy_property_map(), out, sl@0: params).second; sl@0: } sl@0: sl@0: template sl@0: OutputIterator sl@0: articulation_points(const Graph& g, OutputIterator out) sl@0: { sl@0: return biconnected_components(g, dummy_property_map(), out, sl@0: bgl_named_params(0)).second; sl@0: } sl@0: sl@0: } // namespace boost sl@0: sl@0: #endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */