Index: biconnected_components.hpp =================================================================== RCS file: /cvsroot/boost/boost/boost/graph/biconnected_components.hpp,v retrieving revision 1.9 diff -b -u -2 -r1.9 biconnected_components.hpp --- biconnected_components.hpp 3 Nov 2004 15:40:09 -0000 1.9 +++ biconnected_components.hpp 19 Feb 2005 22:23:24 -0000 @@ -19,4 +19,6 @@ #include #include +#include +#include namespace boost @@ -24,42 +26,90 @@ namespace detail { - template - OutputIterator - biconnect(typename graph_traits < Graph >::vertex_descriptor v, - typename graph_traits < Graph >::vertex_descriptor u, - bool at_top, - const Graph & g, + template + struct biconnected_components_visitor : public dfs_visitor<> + { + biconnected_components_visitor( ComponentMap comp, - std::size_t & c, - DiscoverTimeMap d, - std::size_t & dfs_time, LowPointMap lowpt, + std::size_t& c, + DiscoverTimeMap dtm, + std::size_t& dfs_time, + LowPointMap lowpt, + PredecessorMap pred, OutputIterator out, - Stack & S) + Stack& S) : + comp(comp), + c(c), + dtm(dtm), + dfs_time(dfs_time), + lowpt(lowpt), + pred(pred), + out(out), + S(S) { } + + template + void start_vertex(const Vertex& u, Graph&) + { + put(pred, u, u); + } + + template + void discover_vertex(const Vertex& u, Graph&) + { + put(dtm, u, ++dfs_time); + put(lowpt, u, get(dtm, u)); + } + + template + void tree_edge(const Edge& e, Graph& g) + { + S.push(e); + put(pred, target(e, g), source(e, g)); + } + + template + void back_edge(const Edge& e, Graph& g) { BOOST_USING_STD_MIN(); - typedef typename graph_traits < Graph >::vertex_descriptor vertex_t; - typedef typename property_traits < DiscoverTimeMap >::value_type D; - D infinity = (std::numeric_limits < D >::max)(); - put(d, v, ++dfs_time); - put(lowpt, v, get(d, v)); + if ( target(e, g) != get(pred, source(e, g)) ) + { + S.push(e); + put(lowpt, source(e, g), min BOOST_PREVENT_MACRO_SUBSTITUTION( + get(lowpt, source(e, g)), get(dtm, target(e, g)))); + } + } + + template + void finish_vertex(const Vertex& u, Graph& g) + { + BOOST_USING_STD_MIN(); + Vertex parent = get(pred, u); bool is_art_point = false; - std::size_t visited_children = 0; - typename graph_traits < Graph >::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) - { - vertex_t w = target(*ei, g); - if (get(d, w) == infinity) - { - ++visited_children; - S.push(*ei); - out = biconnect(w, v, false, g, comp, c, d, dfs_time, lowpt, out, S); - put(lowpt, v, min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, v), get(lowpt, w))); - if (get(lowpt, w) >= get(d, v)) + if ( get(dtm, parent) > get(dtm, u) ) + { + parent = get(pred, parent); + is_art_point = true; + } + if ( parent == u ) // at top + { + if ( get(dtm, u) + 1 == get(dtm, get(pred, u)) ) + is_art_point = false; + } + else { - if (!at_top) is_art_point = true; + put(lowpt, parent, min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent), get(lowpt, u))); + + if (get(lowpt, u) >= get(dtm, parent)) + { + if ( get(dtm, parent) > get(dtm, get(pred, parent)) ) + { + put(pred, u, get(pred, parent)); + put(pred, parent, u); + } - while (d[source(S.top(), g)] >= d[w]) { + while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) + { put(comp, S.top(), c); S.pop(); @@ -68,29 +118,32 @@ S.pop(); ++c; - - } - } else if (get(d, w) < get(d, v) && (!at_top && w != u)) + if ( S.empty() ) { - S.push(*ei); - put(lowpt, v, min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, v), get(d, w))); + put(pred, u, parent); + put(pred, parent, u); } } - - if (at_top && visited_children > 1) - is_art_point = true; - if (is_art_point) - *out++ = v; - - return out; } - + if ( is_art_point ) + *out++ = u; } + ComponentMap comp; + std::size_t& c; + DiscoverTimeMap dtm; + std::size_t& dfs_time; + LowPointMap lowpt; + PredecessorMap pred; + OutputIterator out; + Stack& S; + + }; + } // namespace detail + template + typename DiscoverTimeMap, typename LowPointMap, typename PredecessorMap> std::pair - biconnected_components(const Graph & g, ComponentMap comp, - OutputIterator out, DiscoverTimeMap discover_time, - LowPointMap lowpt) + biconnected_components(const Graph & g, ComponentMap comp, OutputIterator out, + DiscoverTimeMap discover_time, LowPointMap lowpt, PredecessorMap pred) { typedef typename graph_traits < Graph >::vertex_descriptor vertex_t; @@ -104,20 +157,35 @@ function_requires < ReadWritePropertyMapConcept < LowPointMap, vertex_t > >(); + function_requires < ReadWritePropertyMapConcept < PredecessorMap, + vertex_t > >(); - typedef typename property_traits < DiscoverTimeMap >::value_type D; std::size_t num_components = 0; std::size_t dfs_time = 0; std::stack < edge_t > S; - typename graph_traits < Graph >::vertex_iterator wi, wi_end; - std::size_t infinity = (std::numeric_limits < std::size_t >::max)(); - for (tie(wi, wi_end) = vertices(g); wi != wi_end; ++wi) - put(discover_time, *wi, infinity); - - for (tie(wi, wi_end) = vertices(g); wi != wi_end; ++wi) - if (get(discover_time, *wi) == (std::numeric_limits < D >::max)()) - out = detail::biconnect(*wi, *wi, true, g, comp, num_components, - discover_time, dfs_time, lowpt, out, S); - return std::pair(num_components, out); + detail::biconnected_components_visitor::iterator, + typename property_map::type, vertex_t, vertex_t&>, + LowPointMap, OutputIterator, std::stack > + vis(comp, num_components, discover_time, dfs_time, + lowpt, pred, out, S); + + depth_first_search(g, visitor(vis)); + + return std::pair(num_components, vis.out); + } + + template + std::pair + biconnected_components(const Graph & g, ComponentMap comp, + OutputIterator out, DiscoverTimeMap discover_time, + LowPointMap lowpt) + { + typedef typename graph_traits::vertex_descriptor vertex_t; + std::vector pred(num_vertices(g)); + + return biconnected_components(g, comp, out, discover_time, lowpt, + make_iterator_property_map(pred.begin(), get(vertex_index, g))); }