File indexing completed on 2025-01-18 09:37:10
0001
0002
0003
0004
0005
0006
0007
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
0026
0027
0028
0029
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
0099
0100
0101
0102
0103
0104
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
0121
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
0131
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
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
0143 std::fill_n(header, num_components, num_nodes);
0144
0145
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 }
0199
0200 }
0201
0202 #if defined(__sgi) && !defined(__GNUC__)
0203 #pragma reset woff 1234
0204 #endif
0205
0206 #endif