Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:37:10

0001 //=======================================================================
0002 // Copyright 1997, 1998, 1999, 2000 University of Notre Dame.
0003 // Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek
0004 //
0005 // Distributed under the Boost Software License, Version 1.0. (See
0006 // accompanying file LICENSE_1_0.txt or copy at
0007 // http://www.boost.org/LICENSE_1_0.txt)
0008 //=======================================================================
0009 #ifndef BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
0010 #define BOOST_GRAPH_DETAIL_CONNECTED_COMPONENTS_HPP
0011 
0012 #if defined(__sgi) && !defined(__GNUC__)
0013 #pragma set woff 1234
0014 #endif
0015 
0016 #include <boost/operators.hpp>
0017 
0018 namespace boost
0019 {
0020 
0021 namespace detail
0022 {
0023 
0024     //=========================================================================
0025     // Implementation details of connected_components
0026 
0027     // This is used both in the connected_components algorithm and in
0028     // the kosaraju strong components algorithm during the second DFS
0029     // traversal.
0030     template < class ComponentsPA, class DFSVisitor >
0031     class components_recorder : public DFSVisitor
0032     {
0033         typedef typename property_traits< ComponentsPA >::value_type comp_type;
0034 
0035     public:
0036         components_recorder(ComponentsPA c, comp_type& c_count, DFSVisitor v)
0037         : DFSVisitor(v), m_component(c), m_count(c_count)
0038         {
0039         }
0040 
0041         template < class Vertex, class Graph >
0042         void start_vertex(Vertex u, Graph& g)
0043         {
0044             ++m_count;
0045             DFSVisitor::start_vertex(u, g);
0046         }
0047         template < class Vertex, class Graph >
0048         void discover_vertex(Vertex u, Graph& g)
0049         {
0050             put(m_component, u, m_count);
0051             DFSVisitor::discover_vertex(u, g);
0052         }
0053 
0054     protected:
0055         ComponentsPA m_component;
0056         comp_type& m_count;
0057     };
0058 
0059     template < class DiscoverTimeMap, class FinishTimeMap, class TimeT,
0060         class DFSVisitor >
0061     class time_recorder : public DFSVisitor
0062     {
0063     public:
0064         time_recorder(
0065             DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor v)
0066         : DFSVisitor(v), m_discover_time(d), m_finish_time(f), m_t(t)
0067         {
0068         }
0069 
0070         template < class Vertex, class Graph >
0071         void discover_vertex(Vertex u, Graph& g)
0072         {
0073             put(m_discover_time, u, ++m_t);
0074             DFSVisitor::discover_vertex(u, g);
0075         }
0076         template < class Vertex, class Graph >
0077         void finish_vertex(Vertex u, Graph& g)
0078         {
0079             put(m_finish_time, u, ++m_t);
0080             DFSVisitor::discover_vertex(u, g);
0081         }
0082 
0083     protected:
0084         DiscoverTimeMap m_discover_time;
0085         FinishTimeMap m_finish_time;
0086         TimeT m_t;
0087     };
0088     template < class DiscoverTimeMap, class FinishTimeMap, class TimeT,
0089         class DFSVisitor >
0090     time_recorder< DiscoverTimeMap, FinishTimeMap, TimeT, DFSVisitor >
0091     record_times(DiscoverTimeMap d, FinishTimeMap f, TimeT& t, DFSVisitor vis)
0092     {
0093         return time_recorder< DiscoverTimeMap, FinishTimeMap, TimeT,
0094             DFSVisitor >(d, f, t, vis);
0095     }
0096 
0097     //=========================================================================
0098     // Implementation detail of dynamic_components
0099 
0100     //-------------------------------------------------------------------------
0101     // Helper functions for the component_index class
0102 
0103     // Record the representative vertices in the header array.
0104     // Representative vertices now point to the component number.
0105 
0106     template < class Parent, class OutputIterator, class Integer >
0107     inline void build_components_header(
0108         Parent p, OutputIterator header, Integer num_nodes)
0109     {
0110         Parent component = p;
0111         Integer component_num = 0;
0112         for (Integer v = 0; v != num_nodes; ++v)
0113             if (p[v] == v)
0114             {
0115                 *header++ = v;
0116                 component[v] = component_num++;
0117             }
0118     }
0119 
0120     // Pushes x onto the front of the list. The list is represented in
0121     // an array.
0122     template < class Next, class T, class V >
0123     inline void push_front(Next next, T& head, V x)
0124     {
0125         T tmp = head;
0126         head = x;
0127         next[x] = tmp;
0128     }
0129 
0130     // Create a linked list of the vertices in each component
0131     // by reusing the representative array.
0132     template < class Parent1, class Parent2, class Integer >
0133     void link_components(Parent1 component, Parent2 header, Integer num_nodes,
0134         Integer num_components)
0135     {
0136         // Make the non-representative vertices point to their component
0137         Parent1 representative = component;
0138         for (Integer v = 0; v != num_nodes; ++v)
0139             if (component[v] >= num_components || header[component[v]] != v)
0140                 component[v] = component[representative[v]];
0141 
0142         // initialize the "head" of the lists to "NULL"
0143         std::fill_n(header, num_components, num_nodes);
0144 
0145         // Add each vertex to the linked list for its component
0146         Parent1 next = component;
0147         for (Integer k = 0; k != num_nodes; ++k)
0148             push_front(next, header[component[k]], k);
0149     }
0150 
0151     template < class IndexContainer, class HeaderContainer >
0152     void construct_component_index(
0153         IndexContainer& index, HeaderContainer& header)
0154     {
0155         build_components_header(index.begin(), std::back_inserter(header),
0156             index.end() - index.begin());
0157 
0158         link_components(index.begin(), header.begin(),
0159             index.end() - index.begin(), header.end() - header.begin());
0160     }
0161 
0162     template < class IndexIterator, class Integer, class Distance >
0163     class component_iterator
0164     : boost::forward_iterator_helper<
0165           component_iterator< IndexIterator, Integer, Distance >, Integer,
0166           Distance, Integer*, Integer& >
0167     {
0168     public:
0169         typedef component_iterator self;
0170 
0171         IndexIterator next;
0172         Integer node;
0173 
0174         typedef std::forward_iterator_tag iterator_category;
0175         typedef Integer value_type;
0176         typedef Integer& reference;
0177         typedef Integer* pointer;
0178         typedef Distance difference_type;
0179 
0180         component_iterator() {}
0181         component_iterator(IndexIterator x, Integer i) : next(x), node(i) {}
0182         Integer operator*() const { return node; }
0183         self& operator++()
0184         {
0185             node = next[node];
0186             return *this;
0187         }
0188     };
0189 
0190     template < class IndexIterator, class Integer, class Distance >
0191     inline bool operator==(
0192         const component_iterator< IndexIterator, Integer, Distance >& x,
0193         const component_iterator< IndexIterator, Integer, Distance >& y)
0194     {
0195         return x.node == y.node;
0196     }
0197 
0198 } // namespace detail
0199 
0200 } // namespace detail
0201 
0202 #if defined(__sgi) && !defined(__GNUC__)
0203 #pragma reset woff 1234
0204 #endif
0205 
0206 #endif