Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r75067 - trunk/boost/graph
From: jewillco_at_[hidden]
Date: 2011-10-19 16:03:55


Author: jewillco
Date: 2011-10-19 16:03:54 EDT (Wed, 19 Oct 2011)
New Revision: 75067
URL: http://svn.boost.org/trac/boost/changeset/75067

Log:
Fixed strange use of pred map, and changed algorithm to be more similar to Tarjan paper cited in bibliography; fixes #6033
Text files modified:
   trunk/boost/graph/biconnected_components.hpp | 79 +++++++++++++++++++--------------------
   1 files changed, 38 insertions(+), 41 deletions(-)

Modified: trunk/boost/graph/biconnected_components.hpp
==============================================================================
--- trunk/boost/graph/biconnected_components.hpp (original)
+++ trunk/boost/graph/biconnected_components.hpp 2011-10-19 16:03:54 EDT (Wed, 19 Oct 2011)
@@ -35,19 +35,21 @@
         (ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm,
          std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred,
          OutputIterator out, Stack& S, DFSVisitor vis)
- : comp(comp), c(c), dtm(dtm), dfs_time(dfs_time), lowpt(lowpt),
+ : comp(comp), c(c), children_of_root(0), dtm(dtm),
+ dfs_time(dfs_time), lowpt(lowpt),
             pred(pred), out(out), S(S), vis(vis) { }
 
       template <typename Vertex, typename Graph>
       void initialize_vertex(const Vertex& u, Graph& g)
       {
+ put(pred, u, u);
         vis.initialize_vertex(u, g);
       }
 
       template <typename Vertex, typename Graph>
       void start_vertex(const Vertex& u, Graph& g)
       {
- put(pred, u, u);
+ children_of_root = 0;
         vis.start_vertex(u, g);
       }
 
@@ -68,8 +70,14 @@
       template <typename Edge, typename Graph>
       void tree_edge(const Edge& e, Graph& g)
       {
+ typename boost::graph_traits<Graph>::vertex_descriptor src = source(e, g);
+ typename boost::graph_traits<Graph>::vertex_descriptor tgt = target(e, g);
+
         S.push(e);
- put(pred, target(e, g), source(e, g));
+ put(pred, tgt, src);
+ if ( get(pred, src) == src ) {
+ ++children_of_root;
+ }
         vis.tree_edge(e, g);
       }
 
@@ -78,11 +86,14 @@
       {
         BOOST_USING_STD_MIN();
 
- if ( target(e, g) != get(pred, source(e, g)) ) {
+ typename boost::graph_traits<Graph>::vertex_descriptor src = source(e, g);
+ typename boost::graph_traits<Graph>::vertex_descriptor tgt = target(e, g);
+ if ( ( tgt != get(pred, src) || get(pred, src) == src ) &&
+ get(dtm, tgt) < get(dtm, src) ) {
           S.push(e);
- put(lowpt, source(e, g),
- min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, source(e, g)),
- get(dtm, target(e, g))));
+ put(lowpt, src,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, src),
+ get(dtm, tgt)));
         }
         vis.back_edge(e, g);
       }
@@ -98,49 +109,35 @@
       {
         BOOST_USING_STD_MIN();
         Vertex parent = get(pred, u);
- const std::size_t dtm_of_dubious_parent = get(dtm, parent);
- bool is_art_point = false;
- if ( dtm_of_dubious_parent > get(dtm, u) ) {
- parent = get(pred, parent);
- is_art_point = true;
- put(pred, get(pred, u), u);
- put(pred, u, parent);
+ if (parent == u) { // Root of tree is special
+ if (children_of_root >= 2) {
+ *out++ = u;
+ }
+ return;
         }
-
- if ( parent == u ) { // at top
- if ( get(dtm, u) + 1 == dtm_of_dubious_parent )
- is_art_point = false;
- } else {
- 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 ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) {
- put(comp, S.top(), c);
- S.pop();
- }
+ put(lowpt, parent,
+ min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent),
+ get(lowpt, u)));
+ if ( get(lowpt, u) >= get(dtm, parent) ) {
+ if ( get(pred, parent) != parent ) {
+ *out++ = parent;
+ }
+ while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) {
             put(comp, S.top(), c);
- S.pop();
- ++c;
- if ( S.empty() ) {
- put(pred, u, parent);
- put(pred, parent, u);
- }
+ S.pop();
           }
+ assert (source(S.top(), g) == parent);
+ assert (target(S.top(), g) == u);
+ put(comp, S.top(), c);
+ S.pop();
+ ++c;
         }
- if ( is_art_point )
- *out++ = u;
         vis.finish_vertex(u, g);
       }
 
       ComponentMap comp;
       std::size_t& c;
+ std::size_t children_of_root;
       DiscoverTimeMap dtm;
       std::size_t& dfs_time;
       LowPointMap lowpt;


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk