williamr@2: // williamr@2: //======================================================================= williamr@2: // Copyright 1997-2001 University of Notre Dame. williamr@2: // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek williamr@2: // williamr@2: // Distributed under the Boost Software License, Version 1.0. (See williamr@2: // accompanying file LICENSE_1_0.txt or copy at williamr@2: // http://www.boost.org/LICENSE_1_0.txt) williamr@2: //======================================================================= williamr@2: // williamr@2: #ifndef BOOST_GRAPH_CONNECTED_COMPONENTS_HPP williamr@2: #define BOOST_GRAPH_CONNECTED_COMPONENTS_HPP williamr@2: williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: #include williamr@2: williamr@2: #include williamr@2: williamr@2: namespace boost { williamr@2: williamr@2: namespace detail { williamr@2: williamr@2: // This visitor is used both in the connected_components algorithm williamr@2: // and in the kosaraju strong components algorithm during the williamr@2: // second DFS traversal. williamr@2: template williamr@2: class components_recorder : public dfs_visitor<> williamr@2: { williamr@2: typedef typename property_traits::value_type comp_type; williamr@2: public: williamr@2: components_recorder(ComponentsMap c, williamr@2: comp_type& c_count) williamr@2: : m_component(c), m_count(c_count) {} williamr@2: williamr@2: template williamr@2: void start_vertex(Vertex, Graph&) { williamr@2: if (m_count == (std::numeric_limits::max)()) williamr@2: m_count = 0; // start counting components at zero williamr@2: else williamr@2: ++m_count; williamr@2: } williamr@2: template williamr@2: void discover_vertex(Vertex u, Graph&) { williamr@2: put(m_component, u, m_count); williamr@2: } williamr@2: protected: williamr@2: ComponentsMap m_component; williamr@2: comp_type& m_count; williamr@2: }; williamr@2: williamr@2: } // namespace detail williamr@2: williamr@2: // This function computes the connected components of an undirected williamr@2: // graph using a single application of depth first search. williamr@2: williamr@2: template williamr@2: inline typename property_traits::value_type williamr@2: connected_components(const Graph& g, ComponentMap c, williamr@2: const bgl_named_params& params) williamr@2: { williamr@2: if (num_vertices(g) == 0) return 0; williamr@2: williamr@2: typedef typename graph_traits::vertex_descriptor Vertex; williamr@2: function_requires< WritablePropertyMapConcept >(); williamr@2: typedef typename boost::graph_traits::directed_category directed; williamr@2: BOOST_STATIC_ASSERT((boost::is_same::value)); williamr@2: williamr@2: typedef typename property_traits::value_type comp_type; williamr@2: // c_count initialized to "nil" (with nil represented by (max)()) williamr@2: comp_type c_count((std::numeric_limits::max)()); williamr@2: detail::components_recorder vis(c, c_count); williamr@2: depth_first_search(g, params.visitor(vis)); williamr@2: return c_count + 1; williamr@2: } williamr@2: williamr@2: template williamr@2: inline typename property_traits::value_type williamr@2: connected_components(const Graph& g, ComponentMap c) williamr@2: { williamr@2: if (num_vertices(g) == 0) return 0; williamr@2: williamr@2: typedef typename graph_traits::vertex_descriptor Vertex; williamr@2: function_requires< WritablePropertyMapConcept >(); williamr@2: typedef typename boost::graph_traits::directed_category directed; williamr@2: BOOST_STATIC_ASSERT((boost::is_same::value)); williamr@2: williamr@2: typedef typename property_traits::value_type comp_type; williamr@2: // c_count initialized to "nil" (with nil represented by (max)()) williamr@2: comp_type c_count((std::numeric_limits::max)()); williamr@2: detail::components_recorder vis(c, c_count); williamr@2: depth_first_search(g, visitor(vis)); williamr@2: return c_count + 1; williamr@2: } williamr@2: williamr@2: williamr@2: } // namespace boost williamr@2: williamr@2: williamr@2: #endif // BOOST_GRAPH_CONNECTED_COMPONENTS_HPP