From fa461fe18a0b0663a65e67f3dc7b183c09dd65e1 Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Sat, 24 Feb 2001 07:31:37 +0000 Subject: [PATCH] new file [SVN r9320] --- example/strongly_connected_components.cpp | 57 ++++++++++++++++ include/boost/graph/tarjan_scc.hpp | 79 +++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 example/strongly_connected_components.cpp create mode 100644 include/boost/graph/tarjan_scc.hpp diff --git a/example/strongly_connected_components.cpp b/example/strongly_connected_components.cpp new file mode 100644 index 00000000..9a9068af --- /dev/null +++ b/example/strongly_connected_components.cpp @@ -0,0 +1,57 @@ +//======================================================================= +// Copyright 1997-2001 University of Notre Dame. +// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek +// +// This file is part of the Boost Graph Library +// +// You should have received a copy of the License Agreement for the +// Boost Graph Library along with the software; see the file LICENSE. +// If not, contact Office of Research, University of Notre Dame, Notre +// Dame, IN 46556. +// +// Permission to modify the code and to distribute modified code is +// granted, provided the text of this NOTICE is retained, a notice that +// the code was modified is included with the above COPYRIGHT NOTICE and +// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE +// file is distributed with the modified code. +// +// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. +// By way of example, but not limitation, Licensor MAKES NO +// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY +// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS +// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS +// OR OTHER RIGHTS. +//======================================================================= + +#include +#include +#include +#include +#include + +int main(int, char*[]) +{ + using namespace boost; + const char* name = "abcdefghij"; + + GraphvizGraph G; + read_graphviz("scc2.dot", G); + + typedef graph_traits::vertex_descriptor Vertex; + + std::vector comp(num_vertices(G)), dfs_numbers(num_vertices(G)); + std::vector color(num_vertices(G)); + std::vector root(num_vertices(G)); + int num = tarjan_scc(G, &comp[0], &root[0], &color[0], &dfs_numbers[0]); + + cout << "A directed graph:" << endl; + print_graph(G, name); + cout << endl; + cout << "Total number of components: " << num << endl; + std::vector::iterator i; + for (i = comp.begin(); i != comp.end(); ++i) + cout << "Vertex " << name[i - comp.begin()] + <<" is in component " << *i << endl; + + return 0; +} diff --git a/include/boost/graph/tarjan_scc.hpp b/include/boost/graph/tarjan_scc.hpp new file mode 100644 index 00000000..17672efe --- /dev/null +++ b/include/boost/graph/tarjan_scc.hpp @@ -0,0 +1,79 @@ +#ifndef BOOST_TARJAN_SCC_HPP +#define BOOST_TARJAN_SCC_HPP + +#include + +namespace boost { + + namespace detail { + + template + class tarjan_scc_visitor : public dfs_visitor<> { + typedef typename property_traits::value_type comp_type; + typedef typename property_traits::value_type time_type; + public: + tarjan_scc_visitor(ComponentMap comp_map, RootMap r, DFSNumberMap n, + comp_type& c_, Stack& s_) + : c(c_), comp(comp_map), root(r), dfs_number(n), + dfs_time(time_type()), s(s_) { } + + template + void discover_vertex(Vertex v, Graph& ) { + root[v] = v; + comp[v] = std::numeric_limits::max(); + dfs_number[v] = dfs_time++; + s.push(v); + } + template + void finish_vertex(Vertex v, Graph& g) { + Vertex w; + typename graph_traits::out_edge_iterator ei, ei_end; + for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) { + w = target(*ei, g); + if (comp[w] == std::numeric_limits::max()) + root[v] = this->min_dfs_number(root[v], root[w]); + } + if (root[v] == v) { + do { + w = s.top(); s.pop(); + comp[w] = c; + } while (w != v); + ++c; + } + } + private: + template + Vertex min_dfs_number(Vertex u, Vertex v) { + return dfs_number[u] < dfs_number[v] ? u : v; + } + + comp_type& c; + ComponentMap comp; + RootMap root; + DFSNumberMap dfs_number; + time_type dfs_time; + Stack& s; + }; + + } // namespace detail + + template + typename property_traits::value_type + tarjan_scc(Graph& g, // Input + ComponentMap comp, // Output + // Internal record keeping + RootMap root, ColorMap color, DFSNumberMap dfs_number_map) + { + typename property_traits::value_type total = 0; + typedef std::stack::vertex_descriptor> Stack; + Stack s; + detail::tarjan_scc_visitor + vis(comp, root, dfs_number_map, total, s); + depth_first_search(g, vis, color); + return total; + } +} // namespace boost + +#endif // BOOST_TARJAN_SCC_HPP