diff --git a/example/biconnected_components.cpp b/example/biconnected_components.cpp new file mode 100644 index 00000000..372838e2 --- /dev/null +++ b/example/biconnected_components.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include + +namespace boost +{ + struct edge_component_t + { + enum + { num = 555 }; + typedef edge_property_tag kind; + } + edge_component; +} + +int +main() +{ + using namespace boost; + typedef adjacency_list < vecS, vecS, undirectedS, + no_property, property < edge_component_t, std::size_t > >graph_t; + typedef graph_traits < graph_t >::vertex_descriptor vertex_t; + graph_t g(9); + add_edge(0, 5, g); + add_edge(0, 1, g); + add_edge(0, 6, g); + add_edge(1, 2, g); + add_edge(1, 3, g); + add_edge(1, 4, g); + add_edge(2, 3, g); + add_edge(4, 5, g); + add_edge(6, 8, g); + add_edge(6, 7, g); + add_edge(7, 8, g); + + std::size_t c = 0; + std::vector < std::size_t > discover_time(num_vertices(g)); + std::vector < vertex_t > lowpt(num_vertices(g)); + property_map < graph_t, edge_component_t >::type + component = get(edge_component, g); + biconnected_components(0, 8, g, component, c, &discover_time[0], &lowpt[0]); + + std::cout << "graph A {\n" << " node[shape=\"circle\"]\n"; + + graph_traits < graph_t >::edge_iterator ei, ei_end; + for (tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) + std::cout << source(*ei, g) << " -- " << target(*ei, g) + << "[label=\"" << component[*ei] << "\"]\n"; + std::cout << "}\n"; + + return 0; +} diff --git a/include/boost/graph/biconnected_components.hpp b/include/boost/graph/biconnected_components.hpp new file mode 100644 index 00000000..1fc279d1 --- /dev/null +++ b/include/boost/graph/biconnected_components.hpp @@ -0,0 +1,112 @@ +// Copyright (c) Jeremy Siek 2001 +// +// Permission to use, copy, modify, distribute and sell this software +// and its documentation for any purpose is hereby granted without fee, +// provided that the above copyright notice appears in all copies and +// that both that copyright notice and this permission notice appear +// in supporting documentation. Silicon Graphics makes no +// representations about the suitability of this software for any +// purpose. It is provided "as is" without express or implied warranty. + +// NOTE: this final is generated by libs/graph/doc/biconnected_components.w + +#ifndef BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP +#define BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP + +#include +#include +#include +#include +#include + +namespace boost +{ + namespace detail + { + template < typename Graph, typename ComponentMap, + typename DiscoverTimeMap, typename LowPointMap, typename Stack > + void biconnect(typename graph_traits < Graph >::vertex_descriptor v, + typename graph_traits < Graph >::vertex_descriptor u, + bool at_top, + const Graph & g, + ComponentMap comp, + std::size_t & c, + DiscoverTimeMap d, + std::size_t & dfs_time, LowPointMap lowpt, Stack & S) + { + 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)); + 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) + { + S.push(*ei); + biconnect(w, v, false, g, comp, c, d, dfs_time, lowpt, S); + put(lowpt, v, std::min(get(lowpt, v), get(lowpt, w))); + if (get(lowpt, w) >= get(d, v)) + { + while (d[source(S.top(), g)] >= d[w]) { + put(comp, S.top(), c); + S.pop(); + } + put(comp, S.top(), c); + S.pop(); + ++c; + + } + } else if (get(d, w) < get(d, v) && (!at_top && w != u)) + { + S.push(*ei); + put(lowpt, v, std::min(get(lowpt, v), get(d, w))); + } + } + } + + } + + template < typename Graph, typename ComponentMap, + typename DiscoverTimeMap, typename LowPointMap > + void biconnected_components + (typename graph_traits < Graph >::vertex_descriptor v, + typename graph_traits < Graph >::vertex_descriptor u, + const Graph & g, + ComponentMap comp, + std::size_t & num_components, + DiscoverTimeMap discover_time, LowPointMap lowpt) + { + typedef graph_traits < Graph >::vertex_descriptor vertex_t; + typedef graph_traits < Graph >::edge_descriptor edge_t; + function_requires < VertexListGraphConcept < Graph > >(); + function_requires < IncidenceGraphConcept < Graph > >(); + function_requires < WritablePropertyMapConcept < ComponentMap, + edge_t > >(); + function_requires < ReadWritePropertyMapConcept < DiscoverTimeMap, + vertex_t > >(); + function_requires < ReadWritePropertyMapConcept < LowPointMap, + vertex_t > >(); + + typedef typename property_traits < DiscoverTimeMap >::value_type D; + 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()) + detail::biconnect(*wi, *wi, true, + g, comp, num_components, + discover_time, dfs_time, lowpt, S); + + } + +} // namespace boost + +#endif /* BOOST_GRAPH_BICONNECTED_COMPONENTS_HPP */