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 <boost/graph/graph_concepts.hpp>
 #include <boost/property_map.hpp>
+#include <boost/graph/depth_first_search.hpp>
+#include <boost/graph/graph_utility.hpp>
 
 namespace boost
@@ -24,42 +26,90 @@
   namespace detail
   {
-    template <typename Graph, typename ComponentMap, typename DiscoverTimeMap,
-	      typename LowPointMap, typename OutputIterator, typename Stack>
-    OutputIterator
-    biconnect(typename graph_traits < Graph >::vertex_descriptor v,
-	      typename graph_traits < Graph >::vertex_descriptor u,
-	      bool at_top, 
-	      const Graph & g,
+    template <typename ComponentMap, typename DiscoverTimeMap, 
+        typename LowPointMap, typename PredecessorMap, 
+        typename OutputIterator, typename Stack>
+    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 <typename Vertex, typename Graph> 
+      void start_vertex(const Vertex& u, Graph&) 
+      {
+        put(pred, u, u);
+      }
+ 
+      template <typename Vertex, typename Graph> 
+      void discover_vertex(const Vertex& u, Graph&) 
+      { 
+        put(dtm, u, ++dfs_time);
+        put(lowpt, u, get(dtm, u));
+      }
+
+      template <typename Edge, typename Graph>
+      void tree_edge(const Edge& e, Graph& g) 
+      { 
+        S.push(e); 
+        put(pred, target(e, g), source(e, g));
+      }
+
+      template <typename Edge, typename Graph>
+      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 <typename Vertex, typename Graph> 
+      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 Graph, typename ComponentMap, typename OutputIterator,
-	   typename DiscoverTimeMap, typename LowPointMap >
+	   typename DiscoverTimeMap, typename LowPointMap, typename PredecessorMap>
   std::pair<std::size_t, OutputIterator>
-  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<std::size_t, OutputIterator>(num_components, out);
+    detail::biconnected_components_visitor<ComponentMap, DiscoverTimeMap, 
+          iterator_property_map<typename std::vector<vertex_t>::iterator, 
+          typename property_map<Graph, vertex_index_t>::type, vertex_t, vertex_t&>, 
+          LowPointMap, OutputIterator, std::stack<edge_t> > 
+        vis(comp, num_components, discover_time, dfs_time, 
+          lowpt, pred, out, S);
+          
+    depth_first_search(g, visitor(vis));
+
+    return std::pair<std::size_t, OutputIterator>(num_components, vis.out);
+  }
+
+  template<typename Graph, typename ComponentMap, typename OutputIterator,
+	   typename DiscoverTimeMap, typename LowPointMap >
+  std::pair<std::size_t, OutputIterator>
+  biconnected_components(const Graph & g, ComponentMap comp, 
+			 OutputIterator out, DiscoverTimeMap discover_time, 
+			 LowPointMap lowpt)
+  {
+    typedef typename graph_traits<Graph>::vertex_descriptor vertex_t;
+    std::vector<vertex_t> pred(num_vertices(g));
+    
+    return biconnected_components(g, comp, out, discover_time, lowpt,
+        make_iterator_property_map(pred.begin(), get(vertex_index, g)));
   }