| deba@433 |      1 | /* -*- mode: C++; indent-tabs-mode: nil; -*-
 | 
| deba@433 |      2 |  *
 | 
| deba@433 |      3 |  * This file is a part of LEMON, a generic C++ optimization library.
 | 
| deba@433 |      4 |  *
 | 
| alpar@1270 |      5 |  * Copyright (C) 2003-2013
 | 
| deba@433 |      6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 | 
| deba@433 |      7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 | 
| deba@433 |      8 |  *
 | 
| deba@433 |      9 |  * Permission to use, modify and distribute this software is granted
 | 
| deba@433 |     10 |  * provided that this copyright notice appears in all copies. For
 | 
| deba@433 |     11 |  * precise terms see the accompanying LICENSE file.
 | 
| deba@433 |     12 |  *
 | 
| deba@433 |     13 |  * This software is provided "AS IS" with no warranty of any kind,
 | 
| deba@433 |     14 |  * express or implied, and with no claim as to its suitability for any
 | 
| deba@433 |     15 |  * purpose.
 | 
| deba@433 |     16 |  *
 | 
| deba@433 |     17 |  */
 | 
| deba@433 |     18 | 
 | 
| deba@435 |     19 | #ifndef LEMON_CONNECTIVITY_H
 | 
| deba@435 |     20 | #define LEMON_CONNECTIVITY_H
 | 
| deba@433 |     21 | 
 | 
| deba@433 |     22 | #include <lemon/dfs.h>
 | 
| deba@433 |     23 | #include <lemon/bfs.h>
 | 
| deba@433 |     24 | #include <lemon/core.h>
 | 
| deba@433 |     25 | #include <lemon/maps.h>
 | 
| deba@433 |     26 | #include <lemon/adaptors.h>
 | 
| deba@433 |     27 | 
 | 
| deba@433 |     28 | #include <lemon/concepts/digraph.h>
 | 
| deba@433 |     29 | #include <lemon/concepts/graph.h>
 | 
| deba@433 |     30 | #include <lemon/concept_check.h>
 | 
| deba@433 |     31 | 
 | 
| deba@433 |     32 | #include <stack>
 | 
| deba@433 |     33 | #include <functional>
 | 
| deba@433 |     34 | 
 | 
| kpeter@633 |     35 | /// \ingroup graph_properties
 | 
| deba@433 |     36 | /// \file
 | 
| deba@433 |     37 | /// \brief Connectivity algorithms
 | 
| deba@433 |     38 | ///
 | 
| deba@433 |     39 | /// Connectivity algorithms
 | 
| deba@433 |     40 | 
 | 
| deba@433 |     41 | namespace lemon {
 | 
| deba@433 |     42 | 
 | 
| kpeter@633 |     43 |   /// \ingroup graph_properties
 | 
| deba@433 |     44 |   ///
 | 
| kpeter@695 |     45 |   /// \brief Check whether an undirected graph is connected.
 | 
| deba@433 |     46 |   ///
 | 
| kpeter@695 |     47 |   /// This function checks whether the given undirected graph is connected,
 | 
| kpeter@695 |     48 |   /// i.e. there is a path between any two nodes in the graph.
 | 
| kpeter@695 |     49 |   ///
 | 
| kpeter@695 |     50 |   /// \return \c true if the graph is connected.
 | 
| deba@433 |     51 |   /// \note By definition, the empty graph is connected.
 | 
| kpeter@695 |     52 |   ///
 | 
| kpeter@695 |     53 |   /// \see countConnectedComponents(), connectedComponents()
 | 
| kpeter@695 |     54 |   /// \see stronglyConnected()
 | 
| deba@433 |     55 |   template <typename Graph>
 | 
| deba@433 |     56 |   bool connected(const Graph& graph) {
 | 
| deba@433 |     57 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |     58 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |     59 |     if (NodeIt(graph) == INVALID) return true;
 | 
| deba@433 |     60 |     Dfs<Graph> dfs(graph);
 | 
| deba@433 |     61 |     dfs.run(NodeIt(graph));
 | 
| deba@433 |     62 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |     63 |       if (!dfs.reached(it)) {
 | 
| deba@433 |     64 |         return false;
 | 
| deba@433 |     65 |       }
 | 
| deba@433 |     66 |     }
 | 
| deba@433 |     67 |     return true;
 | 
| deba@433 |     68 |   }
 | 
| deba@433 |     69 | 
 | 
| kpeter@633 |     70 |   /// \ingroup graph_properties
 | 
| deba@433 |     71 |   ///
 | 
| deba@433 |     72 |   /// \brief Count the number of connected components of an undirected graph
 | 
| deba@433 |     73 |   ///
 | 
| kpeter@695 |     74 |   /// This function counts the number of connected components of the given
 | 
| kpeter@695 |     75 |   /// undirected graph.
 | 
| deba@433 |     76 |   ///
 | 
| kpeter@695 |     77 |   /// The connected components are the classes of an equivalence relation
 | 
| kpeter@695 |     78 |   /// on the nodes of an undirected graph. Two nodes are in the same class
 | 
| kpeter@695 |     79 |   /// if they are connected with a path.
 | 
| kpeter@695 |     80 |   ///
 | 
| kpeter@695 |     81 |   /// \return The number of connected components.
 | 
| deba@433 |     82 |   /// \note By definition, the empty graph consists
 | 
| deba@433 |     83 |   /// of zero connected components.
 | 
| kpeter@695 |     84 |   ///
 | 
| kpeter@695 |     85 |   /// \see connected(), connectedComponents()
 | 
| deba@433 |     86 |   template <typename Graph>
 | 
| deba@433 |     87 |   int countConnectedComponents(const Graph &graph) {
 | 
| deba@433 |     88 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |     89 |     typedef typename Graph::Node Node;
 | 
| deba@433 |     90 |     typedef typename Graph::Arc Arc;
 | 
| deba@433 |     91 | 
 | 
| deba@433 |     92 |     typedef NullMap<Node, Arc> PredMap;
 | 
| deba@433 |     93 |     typedef NullMap<Node, int> DistMap;
 | 
| deba@433 |     94 | 
 | 
| deba@433 |     95 |     int compNum = 0;
 | 
| deba@433 |     96 |     typename Bfs<Graph>::
 | 
| deba@433 |     97 |       template SetPredMap<PredMap>::
 | 
| deba@433 |     98 |       template SetDistMap<DistMap>::
 | 
| deba@433 |     99 |       Create bfs(graph);
 | 
| deba@433 |    100 | 
 | 
| deba@433 |    101 |     PredMap predMap;
 | 
| deba@433 |    102 |     bfs.predMap(predMap);
 | 
| deba@433 |    103 | 
 | 
| deba@433 |    104 |     DistMap distMap;
 | 
| deba@433 |    105 |     bfs.distMap(distMap);
 | 
| deba@433 |    106 | 
 | 
| deba@433 |    107 |     bfs.init();
 | 
| deba@433 |    108 |     for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 | 
| deba@433 |    109 |       if (!bfs.reached(n)) {
 | 
| deba@433 |    110 |         bfs.addSource(n);
 | 
| deba@433 |    111 |         bfs.start();
 | 
| deba@433 |    112 |         ++compNum;
 | 
| deba@433 |    113 |       }
 | 
| deba@433 |    114 |     }
 | 
| deba@433 |    115 |     return compNum;
 | 
| deba@433 |    116 |   }
 | 
| deba@433 |    117 | 
 | 
| kpeter@633 |    118 |   /// \ingroup graph_properties
 | 
| deba@433 |    119 |   ///
 | 
| deba@433 |    120 |   /// \brief Find the connected components of an undirected graph
 | 
| deba@433 |    121 |   ///
 | 
| kpeter@695 |    122 |   /// This function finds the connected components of the given undirected
 | 
| kpeter@695 |    123 |   /// graph.
 | 
| kpeter@695 |    124 |   ///
 | 
| kpeter@695 |    125 |   /// The connected components are the classes of an equivalence relation
 | 
| kpeter@695 |    126 |   /// on the nodes of an undirected graph. Two nodes are in the same class
 | 
| kpeter@695 |    127 |   /// if they are connected with a path.
 | 
| deba@433 |    128 |   ///
 | 
| kpeter@633 |    129 |   /// \image html connected_components.png
 | 
| kpeter@633 |    130 |   /// \image latex connected_components.eps "Connected components" width=\textwidth
 | 
| kpeter@633 |    131 |   ///
 | 
| kpeter@695 |    132 |   /// \param graph The undirected graph.
 | 
| deba@433 |    133 |   /// \retval compMap A writable node map. The values will be set from 0 to
 | 
| kpeter@695 |    134 |   /// the number of the connected components minus one. Each value of the map
 | 
| kpeter@695 |    135 |   /// will be set exactly once, and the values of a certain component will be
 | 
| deba@433 |    136 |   /// set continuously.
 | 
| kpeter@695 |    137 |   /// \return The number of connected components.
 | 
| kpeter@695 |    138 |   /// \note By definition, the empty graph consists
 | 
| kpeter@695 |    139 |   /// of zero connected components.
 | 
| kpeter@695 |    140 |   ///
 | 
| kpeter@695 |    141 |   /// \see connected(), countConnectedComponents()
 | 
| deba@433 |    142 |   template <class Graph, class NodeMap>
 | 
| deba@433 |    143 |   int connectedComponents(const Graph &graph, NodeMap &compMap) {
 | 
| deba@433 |    144 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |    145 |     typedef typename Graph::Node Node;
 | 
| deba@433 |    146 |     typedef typename Graph::Arc Arc;
 | 
| deba@433 |    147 |     checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
 | 
| deba@433 |    148 | 
 | 
| deba@433 |    149 |     typedef NullMap<Node, Arc> PredMap;
 | 
| deba@433 |    150 |     typedef NullMap<Node, int> DistMap;
 | 
| deba@433 |    151 | 
 | 
| deba@433 |    152 |     int compNum = 0;
 | 
| deba@433 |    153 |     typename Bfs<Graph>::
 | 
| deba@433 |    154 |       template SetPredMap<PredMap>::
 | 
| deba@433 |    155 |       template SetDistMap<DistMap>::
 | 
| deba@433 |    156 |       Create bfs(graph);
 | 
| deba@433 |    157 | 
 | 
| deba@433 |    158 |     PredMap predMap;
 | 
| deba@433 |    159 |     bfs.predMap(predMap);
 | 
| deba@433 |    160 | 
 | 
| deba@433 |    161 |     DistMap distMap;
 | 
| deba@433 |    162 |     bfs.distMap(distMap);
 | 
| deba@433 |    163 | 
 | 
| deba@433 |    164 |     bfs.init();
 | 
| deba@433 |    165 |     for(typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 | 
| deba@433 |    166 |       if(!bfs.reached(n)) {
 | 
| deba@433 |    167 |         bfs.addSource(n);
 | 
| deba@433 |    168 |         while (!bfs.emptyQueue()) {
 | 
| deba@433 |    169 |           compMap.set(bfs.nextNode(), compNum);
 | 
| deba@433 |    170 |           bfs.processNextNode();
 | 
| deba@433 |    171 |         }
 | 
| deba@433 |    172 |         ++compNum;
 | 
| deba@433 |    173 |       }
 | 
| deba@433 |    174 |     }
 | 
| deba@433 |    175 |     return compNum;
 | 
| deba@433 |    176 |   }
 | 
| deba@433 |    177 | 
 | 
| deba@435 |    178 |   namespace _connectivity_bits {
 | 
| deba@433 |    179 | 
 | 
| deba@433 |    180 |     template <typename Digraph, typename Iterator >
 | 
| deba@433 |    181 |     struct LeaveOrderVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    182 |     public:
 | 
| deba@433 |    183 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    184 |       LeaveOrderVisitor(Iterator it) : _it(it) {}
 | 
| deba@433 |    185 | 
 | 
| deba@433 |    186 |       void leave(const Node& node) {
 | 
| deba@433 |    187 |         *(_it++) = node;
 | 
| deba@433 |    188 |       }
 | 
| deba@433 |    189 | 
 | 
| deba@433 |    190 |     private:
 | 
| deba@433 |    191 |       Iterator _it;
 | 
| deba@433 |    192 |     };
 | 
| deba@433 |    193 | 
 | 
| deba@433 |    194 |     template <typename Digraph, typename Map>
 | 
| deba@433 |    195 |     struct FillMapVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    196 |     public:
 | 
| deba@433 |    197 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    198 |       typedef typename Map::Value Value;
 | 
| deba@433 |    199 | 
 | 
| deba@433 |    200 |       FillMapVisitor(Map& map, Value& value)
 | 
| deba@433 |    201 |         : _map(map), _value(value) {}
 | 
| deba@433 |    202 | 
 | 
| deba@433 |    203 |       void reach(const Node& node) {
 | 
| deba@433 |    204 |         _map.set(node, _value);
 | 
| deba@433 |    205 |       }
 | 
| deba@433 |    206 |     private:
 | 
| deba@433 |    207 |       Map& _map;
 | 
| deba@433 |    208 |       Value& _value;
 | 
| deba@433 |    209 |     };
 | 
| deba@433 |    210 | 
 | 
| deba@433 |    211 |     template <typename Digraph, typename ArcMap>
 | 
| deba@435 |    212 |     struct StronglyConnectedCutArcsVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    213 |     public:
 | 
| deba@433 |    214 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    215 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    216 | 
 | 
| deba@435 |    217 |       StronglyConnectedCutArcsVisitor(const Digraph& digraph,
 | 
| deba@435 |    218 |                                       ArcMap& cutMap,
 | 
| deba@435 |    219 |                                       int& cutNum)
 | 
| deba@433 |    220 |         : _digraph(digraph), _cutMap(cutMap), _cutNum(cutNum),
 | 
| deba@435 |    221 |           _compMap(digraph, -1), _num(-1) {
 | 
| deba@433 |    222 |       }
 | 
| deba@433 |    223 | 
 | 
| deba@435 |    224 |       void start(const Node&) {
 | 
| deba@433 |    225 |         ++_num;
 | 
| deba@433 |    226 |       }
 | 
| deba@433 |    227 | 
 | 
| deba@433 |    228 |       void reach(const Node& node) {
 | 
| deba@433 |    229 |         _compMap.set(node, _num);
 | 
| deba@433 |    230 |       }
 | 
| deba@433 |    231 | 
 | 
| deba@433 |    232 |       void examine(const Arc& arc) {
 | 
| deba@433 |    233 |          if (_compMap[_digraph.source(arc)] !=
 | 
| deba@433 |    234 |              _compMap[_digraph.target(arc)]) {
 | 
| deba@433 |    235 |            _cutMap.set(arc, true);
 | 
| deba@433 |    236 |            ++_cutNum;
 | 
| deba@433 |    237 |          }
 | 
| deba@433 |    238 |       }
 | 
| deba@433 |    239 |     private:
 | 
| deba@433 |    240 |       const Digraph& _digraph;
 | 
| deba@433 |    241 |       ArcMap& _cutMap;
 | 
| deba@433 |    242 |       int& _cutNum;
 | 
| deba@433 |    243 | 
 | 
| deba@433 |    244 |       typename Digraph::template NodeMap<int> _compMap;
 | 
| deba@433 |    245 |       int _num;
 | 
| deba@433 |    246 |     };
 | 
| deba@433 |    247 | 
 | 
| deba@433 |    248 |   }
 | 
| deba@433 |    249 | 
 | 
| deba@433 |    250 | 
 | 
| kpeter@633 |    251 |   /// \ingroup graph_properties
 | 
| deba@433 |    252 |   ///
 | 
| kpeter@695 |    253 |   /// \brief Check whether a directed graph is strongly connected.
 | 
| deba@433 |    254 |   ///
 | 
| kpeter@695 |    255 |   /// This function checks whether the given directed graph is strongly
 | 
| kpeter@695 |    256 |   /// connected, i.e. any two nodes of the digraph are
 | 
| deba@433 |    257 |   /// connected with directed paths in both direction.
 | 
| deba@433 |    258 |   ///
 | 
| kpeter@695 |    259 |   /// \return \c true if the digraph is strongly connected.
 | 
| kpeter@695 |    260 |   /// \note By definition, the empty digraph is strongly connected.
 | 
| alpar@956 |    261 |   ///
 | 
| kpeter@695 |    262 |   /// \see countStronglyConnectedComponents(), stronglyConnectedComponents()
 | 
| kpeter@695 |    263 |   /// \see connected()
 | 
| deba@433 |    264 |   template <typename Digraph>
 | 
| deba@433 |    265 |   bool stronglyConnected(const Digraph& digraph) {
 | 
| deba@433 |    266 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| deba@433 |    267 | 
 | 
| deba@433 |    268 |     typedef typename Digraph::Node Node;
 | 
| deba@433 |    269 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| deba@433 |    270 | 
 | 
| deba@433 |    271 |     typename Digraph::Node source = NodeIt(digraph);
 | 
| deba@433 |    272 |     if (source == INVALID) return true;
 | 
| deba@433 |    273 | 
 | 
| deba@435 |    274 |     using namespace _connectivity_bits;
 | 
| deba@433 |    275 | 
 | 
| deba@433 |    276 |     typedef DfsVisitor<Digraph> Visitor;
 | 
| deba@433 |    277 |     Visitor visitor;
 | 
| deba@433 |    278 | 
 | 
| deba@433 |    279 |     DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
 | 
| deba@433 |    280 |     dfs.init();
 | 
| deba@433 |    281 |     dfs.addSource(source);
 | 
| deba@433 |    282 |     dfs.start();
 | 
| deba@433 |    283 | 
 | 
| deba@433 |    284 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@433 |    285 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    286 |         return false;
 | 
| deba@433 |    287 |       }
 | 
| deba@433 |    288 |     }
 | 
| deba@433 |    289 | 
 | 
| deba@433 |    290 |     typedef ReverseDigraph<const Digraph> RDigraph;
 | 
| deba@435 |    291 |     typedef typename RDigraph::NodeIt RNodeIt;
 | 
| deba@433 |    292 |     RDigraph rdigraph(digraph);
 | 
| deba@433 |    293 | 
 | 
| kpeter@695 |    294 |     typedef DfsVisitor<RDigraph> RVisitor;
 | 
| deba@433 |    295 |     RVisitor rvisitor;
 | 
| deba@433 |    296 | 
 | 
| deba@433 |    297 |     DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
 | 
| deba@433 |    298 |     rdfs.init();
 | 
| deba@433 |    299 |     rdfs.addSource(source);
 | 
| deba@433 |    300 |     rdfs.start();
 | 
| deba@433 |    301 | 
 | 
| deba@435 |    302 |     for (RNodeIt it(rdigraph); it != INVALID; ++it) {
 | 
| deba@433 |    303 |       if (!rdfs.reached(it)) {
 | 
| deba@433 |    304 |         return false;
 | 
| deba@433 |    305 |       }
 | 
| deba@433 |    306 |     }
 | 
| deba@433 |    307 | 
 | 
| deba@433 |    308 |     return true;
 | 
| deba@433 |    309 |   }
 | 
| deba@433 |    310 | 
 | 
| kpeter@633 |    311 |   /// \ingroup graph_properties
 | 
| deba@433 |    312 |   ///
 | 
| alpar@956 |    313 |   /// \brief Count the number of strongly connected components of a
 | 
| kpeter@695 |    314 |   /// directed graph
 | 
| deba@433 |    315 |   ///
 | 
| kpeter@695 |    316 |   /// This function counts the number of strongly connected components of
 | 
| kpeter@695 |    317 |   /// the given directed graph.
 | 
| kpeter@695 |    318 |   ///
 | 
| deba@433 |    319 |   /// The strongly connected components are the classes of an
 | 
| kpeter@695 |    320 |   /// equivalence relation on the nodes of a digraph. Two nodes are in
 | 
| deba@433 |    321 |   /// the same class if they are connected with directed paths in both
 | 
| deba@433 |    322 |   /// direction.
 | 
| deba@433 |    323 |   ///
 | 
| kpeter@695 |    324 |   /// \return The number of strongly connected components.
 | 
| kpeter@695 |    325 |   /// \note By definition, the empty digraph has zero
 | 
| deba@433 |    326 |   /// strongly connected components.
 | 
| kpeter@695 |    327 |   ///
 | 
| kpeter@695 |    328 |   /// \see stronglyConnected(), stronglyConnectedComponents()
 | 
| deba@433 |    329 |   template <typename Digraph>
 | 
| deba@433 |    330 |   int countStronglyConnectedComponents(const Digraph& digraph) {
 | 
| deba@433 |    331 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| deba@433 |    332 | 
 | 
| deba@435 |    333 |     using namespace _connectivity_bits;
 | 
| deba@433 |    334 | 
 | 
| deba@433 |    335 |     typedef typename Digraph::Node Node;
 | 
| deba@433 |    336 |     typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    337 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| deba@433 |    338 |     typedef typename Digraph::ArcIt ArcIt;
 | 
| deba@433 |    339 | 
 | 
| deba@433 |    340 |     typedef std::vector<Node> Container;
 | 
| deba@433 |    341 |     typedef typename Container::iterator Iterator;
 | 
| deba@433 |    342 | 
 | 
| deba@433 |    343 |     Container nodes(countNodes(digraph));
 | 
| deba@433 |    344 |     typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
 | 
| deba@433 |    345 |     Visitor visitor(nodes.begin());
 | 
| deba@433 |    346 | 
 | 
| deba@433 |    347 |     DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
 | 
| deba@433 |    348 |     dfs.init();
 | 
| deba@433 |    349 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@433 |    350 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    351 |         dfs.addSource(it);
 | 
| deba@433 |    352 |         dfs.start();
 | 
| deba@433 |    353 |       }
 | 
| deba@433 |    354 |     }
 | 
| deba@433 |    355 | 
 | 
| deba@433 |    356 |     typedef typename Container::reverse_iterator RIterator;
 | 
| deba@433 |    357 |     typedef ReverseDigraph<const Digraph> RDigraph;
 | 
| deba@433 |    358 | 
 | 
| deba@433 |    359 |     RDigraph rdigraph(digraph);
 | 
| deba@433 |    360 | 
 | 
| deba@433 |    361 |     typedef DfsVisitor<Digraph> RVisitor;
 | 
| deba@433 |    362 |     RVisitor rvisitor;
 | 
| deba@433 |    363 | 
 | 
| deba@433 |    364 |     DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
 | 
| deba@433 |    365 | 
 | 
| deba@433 |    366 |     int compNum = 0;
 | 
| deba@433 |    367 | 
 | 
| deba@433 |    368 |     rdfs.init();
 | 
| deba@433 |    369 |     for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
 | 
| deba@433 |    370 |       if (!rdfs.reached(*it)) {
 | 
| deba@433 |    371 |         rdfs.addSource(*it);
 | 
| deba@433 |    372 |         rdfs.start();
 | 
| deba@433 |    373 |         ++compNum;
 | 
| deba@433 |    374 |       }
 | 
| deba@433 |    375 |     }
 | 
| deba@433 |    376 |     return compNum;
 | 
| deba@433 |    377 |   }
 | 
| deba@433 |    378 | 
 | 
| kpeter@633 |    379 |   /// \ingroup graph_properties
 | 
| deba@433 |    380 |   ///
 | 
| deba@433 |    381 |   /// \brief Find the strongly connected components of a directed graph
 | 
| deba@433 |    382 |   ///
 | 
| kpeter@695 |    383 |   /// This function finds the strongly connected components of the given
 | 
| kpeter@695 |    384 |   /// directed graph. In addition, the numbering of the components will
 | 
| kpeter@695 |    385 |   /// satisfy that there is no arc going from a higher numbered component
 | 
| kpeter@695 |    386 |   /// to a lower one (i.e. it provides a topological order of the components).
 | 
| kpeter@695 |    387 |   ///
 | 
| kpeter@695 |    388 |   /// The strongly connected components are the classes of an
 | 
| kpeter@695 |    389 |   /// equivalence relation on the nodes of a digraph. Two nodes are in
 | 
| kpeter@695 |    390 |   /// the same class if they are connected with directed paths in both
 | 
| kpeter@695 |    391 |   /// direction.
 | 
| deba@433 |    392 |   ///
 | 
| kpeter@633 |    393 |   /// \image html strongly_connected_components.png
 | 
| kpeter@633 |    394 |   /// \image latex strongly_connected_components.eps "Strongly connected components" width=\textwidth
 | 
| kpeter@633 |    395 |   ///
 | 
| deba@433 |    396 |   /// \param digraph The digraph.
 | 
| deba@433 |    397 |   /// \retval compMap A writable node map. The values will be set from 0 to
 | 
| deba@433 |    398 |   /// the number of the strongly connected components minus one. Each value
 | 
| kpeter@695 |    399 |   /// of the map will be set exactly once, and the values of a certain
 | 
| kpeter@695 |    400 |   /// component will be set continuously.
 | 
| kpeter@695 |    401 |   /// \return The number of strongly connected components.
 | 
| kpeter@695 |    402 |   /// \note By definition, the empty digraph has zero
 | 
| kpeter@695 |    403 |   /// strongly connected components.
 | 
| kpeter@695 |    404 |   ///
 | 
| kpeter@695 |    405 |   /// \see stronglyConnected(), countStronglyConnectedComponents()
 | 
| deba@433 |    406 |   template <typename Digraph, typename NodeMap>
 | 
| deba@433 |    407 |   int stronglyConnectedComponents(const Digraph& digraph, NodeMap& compMap) {
 | 
| deba@433 |    408 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| deba@433 |    409 |     typedef typename Digraph::Node Node;
 | 
| deba@433 |    410 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| deba@433 |    411 |     checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
 | 
| deba@433 |    412 | 
 | 
| deba@435 |    413 |     using namespace _connectivity_bits;
 | 
| deba@433 |    414 | 
 | 
| deba@433 |    415 |     typedef std::vector<Node> Container;
 | 
| deba@433 |    416 |     typedef typename Container::iterator Iterator;
 | 
| deba@433 |    417 | 
 | 
| deba@433 |    418 |     Container nodes(countNodes(digraph));
 | 
| deba@433 |    419 |     typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
 | 
| deba@433 |    420 |     Visitor visitor(nodes.begin());
 | 
| deba@433 |    421 | 
 | 
| deba@433 |    422 |     DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
 | 
| deba@433 |    423 |     dfs.init();
 | 
| deba@433 |    424 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@433 |    425 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    426 |         dfs.addSource(it);
 | 
| deba@433 |    427 |         dfs.start();
 | 
| deba@433 |    428 |       }
 | 
| deba@433 |    429 |     }
 | 
| deba@433 |    430 | 
 | 
| deba@433 |    431 |     typedef typename Container::reverse_iterator RIterator;
 | 
| deba@433 |    432 |     typedef ReverseDigraph<const Digraph> RDigraph;
 | 
| deba@433 |    433 | 
 | 
| deba@433 |    434 |     RDigraph rdigraph(digraph);
 | 
| deba@433 |    435 | 
 | 
| deba@433 |    436 |     int compNum = 0;
 | 
| deba@433 |    437 | 
 | 
| deba@433 |    438 |     typedef FillMapVisitor<RDigraph, NodeMap> RVisitor;
 | 
| deba@433 |    439 |     RVisitor rvisitor(compMap, compNum);
 | 
| deba@433 |    440 | 
 | 
| deba@433 |    441 |     DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
 | 
| deba@433 |    442 | 
 | 
| deba@433 |    443 |     rdfs.init();
 | 
| deba@433 |    444 |     for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
 | 
| deba@433 |    445 |       if (!rdfs.reached(*it)) {
 | 
| deba@433 |    446 |         rdfs.addSource(*it);
 | 
| deba@433 |    447 |         rdfs.start();
 | 
| deba@433 |    448 |         ++compNum;
 | 
| deba@433 |    449 |       }
 | 
| deba@433 |    450 |     }
 | 
| deba@433 |    451 |     return compNum;
 | 
| deba@433 |    452 |   }
 | 
| deba@433 |    453 | 
 | 
| kpeter@633 |    454 |   /// \ingroup graph_properties
 | 
| deba@433 |    455 |   ///
 | 
| deba@433 |    456 |   /// \brief Find the cut arcs of the strongly connected components.
 | 
| deba@433 |    457 |   ///
 | 
| kpeter@695 |    458 |   /// This function finds the cut arcs of the strongly connected components
 | 
| kpeter@695 |    459 |   /// of the given digraph.
 | 
| kpeter@695 |    460 |   ///
 | 
| kpeter@695 |    461 |   /// The strongly connected components are the classes of an
 | 
| kpeter@695 |    462 |   /// equivalence relation on the nodes of a digraph. Two nodes are in
 | 
| kpeter@695 |    463 |   /// the same class if they are connected with directed paths in both
 | 
| kpeter@695 |    464 |   /// direction.
 | 
| deba@433 |    465 |   /// The strongly connected components are separated by the cut arcs.
 | 
| deba@433 |    466 |   ///
 | 
| kpeter@695 |    467 |   /// \param digraph The digraph.
 | 
| kpeter@695 |    468 |   /// \retval cutMap A writable arc map. The values will be set to \c true
 | 
| kpeter@695 |    469 |   /// for the cut arcs (exactly once for each cut arc), and will not be
 | 
| kpeter@695 |    470 |   /// changed for other arcs.
 | 
| kpeter@695 |    471 |   /// \return The number of cut arcs.
 | 
| deba@433 |    472 |   ///
 | 
| kpeter@695 |    473 |   /// \see stronglyConnected(), stronglyConnectedComponents()
 | 
| deba@433 |    474 |   template <typename Digraph, typename ArcMap>
 | 
| kpeter@695 |    475 |   int stronglyConnectedCutArcs(const Digraph& digraph, ArcMap& cutMap) {
 | 
| deba@433 |    476 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| deba@433 |    477 |     typedef typename Digraph::Node Node;
 | 
| deba@433 |    478 |     typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    479 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| deba@433 |    480 |     checkConcept<concepts::WriteMap<Arc, bool>, ArcMap>();
 | 
| deba@433 |    481 | 
 | 
| deba@435 |    482 |     using namespace _connectivity_bits;
 | 
| deba@433 |    483 | 
 | 
| deba@433 |    484 |     typedef std::vector<Node> Container;
 | 
| deba@433 |    485 |     typedef typename Container::iterator Iterator;
 | 
| deba@433 |    486 | 
 | 
| kpeter@695 |    487 |     Container nodes(countNodes(digraph));
 | 
| deba@433 |    488 |     typedef LeaveOrderVisitor<Digraph, Iterator> Visitor;
 | 
| deba@433 |    489 |     Visitor visitor(nodes.begin());
 | 
| deba@433 |    490 | 
 | 
| kpeter@695 |    491 |     DfsVisit<Digraph, Visitor> dfs(digraph, visitor);
 | 
| deba@433 |    492 |     dfs.init();
 | 
| kpeter@695 |    493 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@433 |    494 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    495 |         dfs.addSource(it);
 | 
| deba@433 |    496 |         dfs.start();
 | 
| deba@433 |    497 |       }
 | 
| deba@433 |    498 |     }
 | 
| deba@433 |    499 | 
 | 
| deba@433 |    500 |     typedef typename Container::reverse_iterator RIterator;
 | 
| deba@433 |    501 |     typedef ReverseDigraph<const Digraph> RDigraph;
 | 
| deba@433 |    502 | 
 | 
| kpeter@695 |    503 |     RDigraph rdigraph(digraph);
 | 
| deba@433 |    504 | 
 | 
| deba@433 |    505 |     int cutNum = 0;
 | 
| deba@433 |    506 | 
 | 
| deba@435 |    507 |     typedef StronglyConnectedCutArcsVisitor<RDigraph, ArcMap> RVisitor;
 | 
| kpeter@695 |    508 |     RVisitor rvisitor(rdigraph, cutMap, cutNum);
 | 
| deba@433 |    509 | 
 | 
| kpeter@695 |    510 |     DfsVisit<RDigraph, RVisitor> rdfs(rdigraph, rvisitor);
 | 
| deba@433 |    511 | 
 | 
| deba@433 |    512 |     rdfs.init();
 | 
| deba@433 |    513 |     for (RIterator it = nodes.rbegin(); it != nodes.rend(); ++it) {
 | 
| deba@433 |    514 |       if (!rdfs.reached(*it)) {
 | 
| deba@433 |    515 |         rdfs.addSource(*it);
 | 
| deba@433 |    516 |         rdfs.start();
 | 
| deba@433 |    517 |       }
 | 
| deba@433 |    518 |     }
 | 
| deba@433 |    519 |     return cutNum;
 | 
| deba@433 |    520 |   }
 | 
| deba@433 |    521 | 
 | 
| deba@435 |    522 |   namespace _connectivity_bits {
 | 
| deba@433 |    523 | 
 | 
| deba@433 |    524 |     template <typename Digraph>
 | 
| deba@433 |    525 |     class CountBiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    526 |     public:
 | 
| deba@433 |    527 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    528 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    529 |       typedef typename Digraph::Edge Edge;
 | 
| deba@433 |    530 | 
 | 
| deba@433 |    531 |       CountBiNodeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
 | 
| deba@433 |    532 |         : _graph(graph), _compNum(compNum),
 | 
| deba@433 |    533 |           _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 | 
| deba@433 |    534 | 
 | 
| deba@433 |    535 |       void start(const Node& node) {
 | 
| deba@433 |    536 |         _predMap.set(node, INVALID);
 | 
| deba@433 |    537 |       }
 | 
| deba@433 |    538 | 
 | 
| deba@433 |    539 |       void reach(const Node& node) {
 | 
| deba@433 |    540 |         _numMap.set(node, _num);
 | 
| deba@433 |    541 |         _retMap.set(node, _num);
 | 
| deba@433 |    542 |         ++_num;
 | 
| deba@433 |    543 |       }
 | 
| deba@433 |    544 | 
 | 
| deba@433 |    545 |       void discover(const Arc& edge) {
 | 
| deba@433 |    546 |         _predMap.set(_graph.target(edge), _graph.source(edge));
 | 
| deba@433 |    547 |       }
 | 
| deba@433 |    548 | 
 | 
| deba@433 |    549 |       void examine(const Arc& edge) {
 | 
| deba@433 |    550 |         if (_graph.source(edge) == _graph.target(edge) &&
 | 
| deba@433 |    551 |             _graph.direction(edge)) {
 | 
| deba@433 |    552 |           ++_compNum;
 | 
| deba@433 |    553 |           return;
 | 
| deba@433 |    554 |         }
 | 
| deba@433 |    555 |         if (_predMap[_graph.source(edge)] == _graph.target(edge)) {
 | 
| deba@433 |    556 |           return;
 | 
| deba@433 |    557 |         }
 | 
| deba@433 |    558 |         if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
 | 
| deba@433 |    559 |           _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
 | 
| deba@433 |    560 |         }
 | 
| deba@433 |    561 |       }
 | 
| deba@433 |    562 | 
 | 
| deba@433 |    563 |       void backtrack(const Arc& edge) {
 | 
| deba@433 |    564 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |    565 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |    566 |         }
 | 
| deba@433 |    567 |         if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
 | 
| deba@433 |    568 |           ++_compNum;
 | 
| deba@433 |    569 |         }
 | 
| deba@433 |    570 |       }
 | 
| deba@433 |    571 | 
 | 
| deba@433 |    572 |     private:
 | 
| deba@433 |    573 |       const Digraph& _graph;
 | 
| deba@433 |    574 |       int& _compNum;
 | 
| deba@433 |    575 | 
 | 
| deba@433 |    576 |       typename Digraph::template NodeMap<int> _numMap;
 | 
| deba@433 |    577 |       typename Digraph::template NodeMap<int> _retMap;
 | 
| deba@433 |    578 |       typename Digraph::template NodeMap<Node> _predMap;
 | 
| deba@433 |    579 |       int _num;
 | 
| deba@433 |    580 |     };
 | 
| deba@433 |    581 | 
 | 
| deba@433 |    582 |     template <typename Digraph, typename ArcMap>
 | 
| deba@433 |    583 |     class BiNodeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    584 |     public:
 | 
| deba@433 |    585 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    586 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    587 |       typedef typename Digraph::Edge Edge;
 | 
| deba@433 |    588 | 
 | 
| deba@433 |    589 |       BiNodeConnectedComponentsVisitor(const Digraph& graph,
 | 
| deba@433 |    590 |                                        ArcMap& compMap, int &compNum)
 | 
| deba@433 |    591 |         : _graph(graph), _compMap(compMap), _compNum(compNum),
 | 
| deba@433 |    592 |           _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 | 
| deba@433 |    593 | 
 | 
| deba@433 |    594 |       void start(const Node& node) {
 | 
| deba@433 |    595 |         _predMap.set(node, INVALID);
 | 
| deba@433 |    596 |       }
 | 
| deba@433 |    597 | 
 | 
| deba@433 |    598 |       void reach(const Node& node) {
 | 
| deba@433 |    599 |         _numMap.set(node, _num);
 | 
| deba@433 |    600 |         _retMap.set(node, _num);
 | 
| deba@433 |    601 |         ++_num;
 | 
| deba@433 |    602 |       }
 | 
| deba@433 |    603 | 
 | 
| deba@433 |    604 |       void discover(const Arc& edge) {
 | 
| deba@433 |    605 |         Node target = _graph.target(edge);
 | 
| deba@433 |    606 |         _predMap.set(target, edge);
 | 
| deba@433 |    607 |         _edgeStack.push(edge);
 | 
| deba@433 |    608 |       }
 | 
| deba@433 |    609 | 
 | 
| deba@433 |    610 |       void examine(const Arc& edge) {
 | 
| deba@433 |    611 |         Node source = _graph.source(edge);
 | 
| deba@433 |    612 |         Node target = _graph.target(edge);
 | 
| deba@433 |    613 |         if (source == target && _graph.direction(edge)) {
 | 
| deba@433 |    614 |           _compMap.set(edge, _compNum);
 | 
| deba@433 |    615 |           ++_compNum;
 | 
| deba@433 |    616 |           return;
 | 
| deba@433 |    617 |         }
 | 
| deba@433 |    618 |         if (_numMap[target] < _numMap[source]) {
 | 
| deba@433 |    619 |           if (_predMap[source] != _graph.oppositeArc(edge)) {
 | 
| deba@433 |    620 |             _edgeStack.push(edge);
 | 
| deba@433 |    621 |           }
 | 
| deba@433 |    622 |         }
 | 
| deba@433 |    623 |         if (_predMap[source] != INVALID &&
 | 
| deba@433 |    624 |             target == _graph.source(_predMap[source])) {
 | 
| deba@433 |    625 |           return;
 | 
| deba@433 |    626 |         }
 | 
| deba@433 |    627 |         if (_retMap[source] > _numMap[target]) {
 | 
| deba@433 |    628 |           _retMap.set(source, _numMap[target]);
 | 
| deba@433 |    629 |         }
 | 
| deba@433 |    630 |       }
 | 
| deba@433 |    631 | 
 | 
| deba@433 |    632 |       void backtrack(const Arc& edge) {
 | 
| deba@433 |    633 |         Node source = _graph.source(edge);
 | 
| deba@433 |    634 |         Node target = _graph.target(edge);
 | 
| deba@433 |    635 |         if (_retMap[source] > _retMap[target]) {
 | 
| deba@433 |    636 |           _retMap.set(source, _retMap[target]);
 | 
| deba@433 |    637 |         }
 | 
| deba@433 |    638 |         if (_numMap[source] <= _retMap[target]) {
 | 
| deba@433 |    639 |           while (_edgeStack.top() != edge) {
 | 
| deba@433 |    640 |             _compMap.set(_edgeStack.top(), _compNum);
 | 
| deba@433 |    641 |             _edgeStack.pop();
 | 
| deba@433 |    642 |           }
 | 
| deba@433 |    643 |           _compMap.set(edge, _compNum);
 | 
| deba@433 |    644 |           _edgeStack.pop();
 | 
| deba@433 |    645 |           ++_compNum;
 | 
| deba@433 |    646 |         }
 | 
| deba@433 |    647 |       }
 | 
| deba@433 |    648 | 
 | 
| deba@433 |    649 |     private:
 | 
| deba@433 |    650 |       const Digraph& _graph;
 | 
| deba@433 |    651 |       ArcMap& _compMap;
 | 
| deba@433 |    652 |       int& _compNum;
 | 
| deba@433 |    653 | 
 | 
| deba@433 |    654 |       typename Digraph::template NodeMap<int> _numMap;
 | 
| deba@433 |    655 |       typename Digraph::template NodeMap<int> _retMap;
 | 
| deba@433 |    656 |       typename Digraph::template NodeMap<Arc> _predMap;
 | 
| deba@433 |    657 |       std::stack<Edge> _edgeStack;
 | 
| deba@433 |    658 |       int _num;
 | 
| deba@433 |    659 |     };
 | 
| deba@433 |    660 | 
 | 
| deba@433 |    661 | 
 | 
| deba@433 |    662 |     template <typename Digraph, typename NodeMap>
 | 
| deba@433 |    663 |     class BiNodeConnectedCutNodesVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    664 |     public:
 | 
| deba@433 |    665 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    666 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    667 |       typedef typename Digraph::Edge Edge;
 | 
| deba@433 |    668 | 
 | 
| deba@433 |    669 |       BiNodeConnectedCutNodesVisitor(const Digraph& graph, NodeMap& cutMap,
 | 
| deba@433 |    670 |                                      int& cutNum)
 | 
| deba@433 |    671 |         : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
 | 
| deba@433 |    672 |           _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 | 
| deba@433 |    673 | 
 | 
| deba@433 |    674 |       void start(const Node& node) {
 | 
| deba@433 |    675 |         _predMap.set(node, INVALID);
 | 
| deba@433 |    676 |         rootCut = false;
 | 
| deba@433 |    677 |       }
 | 
| deba@433 |    678 | 
 | 
| deba@433 |    679 |       void reach(const Node& node) {
 | 
| deba@433 |    680 |         _numMap.set(node, _num);
 | 
| deba@433 |    681 |         _retMap.set(node, _num);
 | 
| deba@433 |    682 |         ++_num;
 | 
| deba@433 |    683 |       }
 | 
| deba@433 |    684 | 
 | 
| deba@433 |    685 |       void discover(const Arc& edge) {
 | 
| deba@433 |    686 |         _predMap.set(_graph.target(edge), _graph.source(edge));
 | 
| deba@433 |    687 |       }
 | 
| deba@433 |    688 | 
 | 
| deba@433 |    689 |       void examine(const Arc& edge) {
 | 
| deba@433 |    690 |         if (_graph.source(edge) == _graph.target(edge) &&
 | 
| deba@433 |    691 |             _graph.direction(edge)) {
 | 
| deba@433 |    692 |           if (!_cutMap[_graph.source(edge)]) {
 | 
| deba@433 |    693 |             _cutMap.set(_graph.source(edge), true);
 | 
| deba@433 |    694 |             ++_cutNum;
 | 
| deba@433 |    695 |           }
 | 
| deba@433 |    696 |           return;
 | 
| deba@433 |    697 |         }
 | 
| deba@433 |    698 |         if (_predMap[_graph.source(edge)] == _graph.target(edge)) return;
 | 
| deba@433 |    699 |         if (_retMap[_graph.source(edge)] > _numMap[_graph.target(edge)]) {
 | 
| deba@433 |    700 |           _retMap.set(_graph.source(edge), _numMap[_graph.target(edge)]);
 | 
| deba@433 |    701 |         }
 | 
| deba@433 |    702 |       }
 | 
| deba@433 |    703 | 
 | 
| deba@433 |    704 |       void backtrack(const Arc& edge) {
 | 
| deba@433 |    705 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |    706 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |    707 |         }
 | 
| deba@433 |    708 |         if (_numMap[_graph.source(edge)] <= _retMap[_graph.target(edge)]) {
 | 
| deba@433 |    709 |           if (_predMap[_graph.source(edge)] != INVALID) {
 | 
| deba@433 |    710 |             if (!_cutMap[_graph.source(edge)]) {
 | 
| deba@433 |    711 |               _cutMap.set(_graph.source(edge), true);
 | 
| deba@433 |    712 |               ++_cutNum;
 | 
| deba@433 |    713 |             }
 | 
| deba@433 |    714 |           } else if (rootCut) {
 | 
| deba@433 |    715 |             if (!_cutMap[_graph.source(edge)]) {
 | 
| deba@433 |    716 |               _cutMap.set(_graph.source(edge), true);
 | 
| deba@433 |    717 |               ++_cutNum;
 | 
| deba@433 |    718 |             }
 | 
| deba@433 |    719 |           } else {
 | 
| deba@433 |    720 |             rootCut = true;
 | 
| deba@433 |    721 |           }
 | 
| deba@433 |    722 |         }
 | 
| deba@433 |    723 |       }
 | 
| deba@433 |    724 | 
 | 
| deba@433 |    725 |     private:
 | 
| deba@433 |    726 |       const Digraph& _graph;
 | 
| deba@433 |    727 |       NodeMap& _cutMap;
 | 
| deba@433 |    728 |       int& _cutNum;
 | 
| deba@433 |    729 | 
 | 
| deba@433 |    730 |       typename Digraph::template NodeMap<int> _numMap;
 | 
| deba@433 |    731 |       typename Digraph::template NodeMap<int> _retMap;
 | 
| deba@433 |    732 |       typename Digraph::template NodeMap<Node> _predMap;
 | 
| deba@433 |    733 |       std::stack<Edge> _edgeStack;
 | 
| deba@433 |    734 |       int _num;
 | 
| deba@433 |    735 |       bool rootCut;
 | 
| deba@433 |    736 |     };
 | 
| deba@433 |    737 | 
 | 
| deba@433 |    738 |   }
 | 
| deba@433 |    739 | 
 | 
| deba@433 |    740 |   template <typename Graph>
 | 
| deba@433 |    741 |   int countBiNodeConnectedComponents(const Graph& graph);
 | 
| deba@433 |    742 | 
 | 
| kpeter@633 |    743 |   /// \ingroup graph_properties
 | 
| deba@433 |    744 |   ///
 | 
| kpeter@695 |    745 |   /// \brief Check whether an undirected graph is bi-node-connected.
 | 
| deba@433 |    746 |   ///
 | 
| deba@1265 |    747 |   /// This function checks whether the given undirected graph is
 | 
| deba@1265 |    748 |   /// bi-node-connected, i.e. a connected graph without articulation
 | 
| deba@1265 |    749 |   /// node.
 | 
| deba@433 |    750 |   ///
 | 
| kpeter@695 |    751 |   /// \return \c true if the graph bi-node-connected.
 | 
| alpar@1266 |    752 |   ///
 | 
| alpar@1266 |    753 |   /// \note By definition,
 | 
| alpar@1266 |    754 |   /// \li a graph consisting of zero or one node is bi-node-connected,
 | 
| alpar@1266 |    755 |   /// \li a graph consisting of two isolated nodes
 | 
| alpar@1266 |    756 |   /// is \e not bi-node-connected and
 | 
| alpar@1266 |    757 |   /// \li a graph consisting of two nodes connected by an edge
 | 
| alpar@1266 |    758 |   /// is bi-node-connected.
 | 
| kpeter@695 |    759 |   ///
 | 
| kpeter@695 |    760 |   /// \see countBiNodeConnectedComponents(), biNodeConnectedComponents()
 | 
| deba@433 |    761 |   template <typename Graph>
 | 
| deba@433 |    762 |   bool biNodeConnected(const Graph& graph) {
 | 
| deba@1265 |    763 |     bool hasNonIsolated = false, hasIsolated = false;
 | 
| deba@1265 |    764 |     for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 | 
| deba@1265 |    765 |       if (typename Graph::OutArcIt(graph, n) == INVALID) {
 | 
| deba@1265 |    766 |         if (hasIsolated || hasNonIsolated) {
 | 
| deba@1265 |    767 |           return false;
 | 
| deba@1265 |    768 |         } else {
 | 
| deba@1265 |    769 |           hasIsolated = true;
 | 
| deba@1265 |    770 |         }
 | 
| deba@1265 |    771 |       } else {
 | 
| deba@1265 |    772 |         if (hasIsolated) {
 | 
| deba@1265 |    773 |           return false;
 | 
| deba@1265 |    774 |         } else {
 | 
| deba@1265 |    775 |           hasNonIsolated = true;
 | 
| deba@1265 |    776 |         }
 | 
| deba@1265 |    777 |       }
 | 
| deba@1265 |    778 |     }
 | 
| deba@433 |    779 |     return countBiNodeConnectedComponents(graph) <= 1;
 | 
| deba@433 |    780 |   }
 | 
| deba@433 |    781 | 
 | 
| kpeter@633 |    782 |   /// \ingroup graph_properties
 | 
| deba@433 |    783 |   ///
 | 
| alpar@956 |    784 |   /// \brief Count the number of bi-node-connected components of an
 | 
| kpeter@695 |    785 |   /// undirected graph.
 | 
| deba@433 |    786 |   ///
 | 
| kpeter@695 |    787 |   /// This function counts the number of bi-node-connected components of
 | 
| kpeter@695 |    788 |   /// the given undirected graph.
 | 
| deba@433 |    789 |   ///
 | 
| kpeter@695 |    790 |   /// The bi-node-connected components are the classes of an equivalence
 | 
| kpeter@695 |    791 |   /// relation on the edges of a undirected graph. Two edges are in the
 | 
| kpeter@695 |    792 |   /// same class if they are on same circle.
 | 
| kpeter@695 |    793 |   ///
 | 
| kpeter@695 |    794 |   /// \return The number of bi-node-connected components.
 | 
| kpeter@695 |    795 |   ///
 | 
| kpeter@695 |    796 |   /// \see biNodeConnected(), biNodeConnectedComponents()
 | 
| deba@433 |    797 |   template <typename Graph>
 | 
| deba@433 |    798 |   int countBiNodeConnectedComponents(const Graph& graph) {
 | 
| deba@433 |    799 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |    800 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |    801 | 
 | 
| deba@435 |    802 |     using namespace _connectivity_bits;
 | 
| deba@433 |    803 | 
 | 
| deba@433 |    804 |     typedef CountBiNodeConnectedComponentsVisitor<Graph> Visitor;
 | 
| deba@433 |    805 | 
 | 
| deba@433 |    806 |     int compNum = 0;
 | 
| deba@433 |    807 |     Visitor visitor(graph, compNum);
 | 
| deba@433 |    808 | 
 | 
| deba@433 |    809 |     DfsVisit<Graph, Visitor> dfs(graph, visitor);
 | 
| deba@433 |    810 |     dfs.init();
 | 
| deba@433 |    811 | 
 | 
| deba@433 |    812 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |    813 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    814 |         dfs.addSource(it);
 | 
| deba@433 |    815 |         dfs.start();
 | 
| deba@433 |    816 |       }
 | 
| deba@433 |    817 |     }
 | 
| deba@433 |    818 |     return compNum;
 | 
| deba@433 |    819 |   }
 | 
| deba@433 |    820 | 
 | 
| kpeter@633 |    821 |   /// \ingroup graph_properties
 | 
| deba@433 |    822 |   ///
 | 
| kpeter@695 |    823 |   /// \brief Find the bi-node-connected components of an undirected graph.
 | 
| deba@433 |    824 |   ///
 | 
| kpeter@695 |    825 |   /// This function finds the bi-node-connected components of the given
 | 
| kpeter@695 |    826 |   /// undirected graph.
 | 
| kpeter@695 |    827 |   ///
 | 
| kpeter@695 |    828 |   /// The bi-node-connected components are the classes of an equivalence
 | 
| kpeter@695 |    829 |   /// relation on the edges of a undirected graph. Two edges are in the
 | 
| kpeter@695 |    830 |   /// same class if they are on same circle.
 | 
| deba@433 |    831 |   ///
 | 
| kpeter@633 |    832 |   /// \image html node_biconnected_components.png
 | 
| kpeter@633 |    833 |   /// \image latex node_biconnected_components.eps "bi-node-connected components" width=\textwidth
 | 
| kpeter@633 |    834 |   ///
 | 
| kpeter@695 |    835 |   /// \param graph The undirected graph.
 | 
| kpeter@695 |    836 |   /// \retval compMap A writable edge map. The values will be set from 0
 | 
| kpeter@695 |    837 |   /// to the number of the bi-node-connected components minus one. Each
 | 
| alpar@956 |    838 |   /// value of the map will be set exactly once, and the values of a
 | 
| kpeter@695 |    839 |   /// certain component will be set continuously.
 | 
| kpeter@695 |    840 |   /// \return The number of bi-node-connected components.
 | 
| kpeter@695 |    841 |   ///
 | 
| kpeter@695 |    842 |   /// \see biNodeConnected(), countBiNodeConnectedComponents()
 | 
| deba@433 |    843 |   template <typename Graph, typename EdgeMap>
 | 
| deba@433 |    844 |   int biNodeConnectedComponents(const Graph& graph,
 | 
| deba@433 |    845 |                                 EdgeMap& compMap) {
 | 
| deba@433 |    846 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |    847 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |    848 |     typedef typename Graph::Edge Edge;
 | 
| deba@433 |    849 |     checkConcept<concepts::WriteMap<Edge, int>, EdgeMap>();
 | 
| deba@433 |    850 | 
 | 
| deba@435 |    851 |     using namespace _connectivity_bits;
 | 
| deba@433 |    852 | 
 | 
| deba@433 |    853 |     typedef BiNodeConnectedComponentsVisitor<Graph, EdgeMap> Visitor;
 | 
| deba@433 |    854 | 
 | 
| deba@433 |    855 |     int compNum = 0;
 | 
| deba@433 |    856 |     Visitor visitor(graph, compMap, compNum);
 | 
| deba@433 |    857 | 
 | 
| deba@433 |    858 |     DfsVisit<Graph, Visitor> dfs(graph, visitor);
 | 
| deba@433 |    859 |     dfs.init();
 | 
| deba@433 |    860 | 
 | 
| deba@433 |    861 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |    862 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    863 |         dfs.addSource(it);
 | 
| deba@433 |    864 |         dfs.start();
 | 
| deba@433 |    865 |       }
 | 
| deba@433 |    866 |     }
 | 
| deba@433 |    867 |     return compNum;
 | 
| deba@433 |    868 |   }
 | 
| deba@433 |    869 | 
 | 
| kpeter@633 |    870 |   /// \ingroup graph_properties
 | 
| deba@433 |    871 |   ///
 | 
| kpeter@695 |    872 |   /// \brief Find the bi-node-connected cut nodes in an undirected graph.
 | 
| deba@433 |    873 |   ///
 | 
| kpeter@695 |    874 |   /// This function finds the bi-node-connected cut nodes in the given
 | 
| kpeter@695 |    875 |   /// undirected graph.
 | 
| deba@433 |    876 |   ///
 | 
| kpeter@695 |    877 |   /// The bi-node-connected components are the classes of an equivalence
 | 
| kpeter@695 |    878 |   /// relation on the edges of a undirected graph. Two edges are in the
 | 
| kpeter@695 |    879 |   /// same class if they are on same circle.
 | 
| kpeter@695 |    880 |   /// The bi-node-connected components are separted by the cut nodes of
 | 
| kpeter@695 |    881 |   /// the components.
 | 
| kpeter@695 |    882 |   ///
 | 
| kpeter@695 |    883 |   /// \param graph The undirected graph.
 | 
| alpar@956 |    884 |   /// \retval cutMap A writable node map. The values will be set to
 | 
| kpeter@695 |    885 |   /// \c true for the nodes that separate two or more components
 | 
| kpeter@695 |    886 |   /// (exactly once for each cut node), and will not be changed for
 | 
| kpeter@695 |    887 |   /// other nodes.
 | 
| deba@433 |    888 |   /// \return The number of the cut nodes.
 | 
| kpeter@695 |    889 |   ///
 | 
| kpeter@695 |    890 |   /// \see biNodeConnected(), biNodeConnectedComponents()
 | 
| deba@433 |    891 |   template <typename Graph, typename NodeMap>
 | 
| deba@433 |    892 |   int biNodeConnectedCutNodes(const Graph& graph, NodeMap& cutMap) {
 | 
| deba@433 |    893 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |    894 |     typedef typename Graph::Node Node;
 | 
| deba@433 |    895 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |    896 |     checkConcept<concepts::WriteMap<Node, bool>, NodeMap>();
 | 
| deba@433 |    897 | 
 | 
| deba@435 |    898 |     using namespace _connectivity_bits;
 | 
| deba@433 |    899 | 
 | 
| deba@433 |    900 |     typedef BiNodeConnectedCutNodesVisitor<Graph, NodeMap> Visitor;
 | 
| deba@433 |    901 | 
 | 
| deba@433 |    902 |     int cutNum = 0;
 | 
| deba@433 |    903 |     Visitor visitor(graph, cutMap, cutNum);
 | 
| deba@433 |    904 | 
 | 
| deba@433 |    905 |     DfsVisit<Graph, Visitor> dfs(graph, visitor);
 | 
| deba@433 |    906 |     dfs.init();
 | 
| deba@433 |    907 | 
 | 
| deba@433 |    908 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |    909 |       if (!dfs.reached(it)) {
 | 
| deba@433 |    910 |         dfs.addSource(it);
 | 
| deba@433 |    911 |         dfs.start();
 | 
| deba@433 |    912 |       }
 | 
| deba@433 |    913 |     }
 | 
| deba@433 |    914 |     return cutNum;
 | 
| deba@433 |    915 |   }
 | 
| deba@433 |    916 | 
 | 
| deba@435 |    917 |   namespace _connectivity_bits {
 | 
| deba@433 |    918 | 
 | 
| deba@433 |    919 |     template <typename Digraph>
 | 
| deba@433 |    920 |     class CountBiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    921 |     public:
 | 
| deba@433 |    922 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    923 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    924 |       typedef typename Digraph::Edge Edge;
 | 
| deba@433 |    925 | 
 | 
| deba@433 |    926 |       CountBiEdgeConnectedComponentsVisitor(const Digraph& graph, int &compNum)
 | 
| deba@433 |    927 |         : _graph(graph), _compNum(compNum),
 | 
| deba@433 |    928 |           _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 | 
| deba@433 |    929 | 
 | 
| deba@433 |    930 |       void start(const Node& node) {
 | 
| deba@433 |    931 |         _predMap.set(node, INVALID);
 | 
| deba@433 |    932 |       }
 | 
| deba@433 |    933 | 
 | 
| deba@433 |    934 |       void reach(const Node& node) {
 | 
| deba@433 |    935 |         _numMap.set(node, _num);
 | 
| deba@433 |    936 |         _retMap.set(node, _num);
 | 
| deba@433 |    937 |         ++_num;
 | 
| deba@433 |    938 |       }
 | 
| deba@433 |    939 | 
 | 
| deba@433 |    940 |       void leave(const Node& node) {
 | 
| deba@433 |    941 |         if (_numMap[node] <= _retMap[node]) {
 | 
| deba@433 |    942 |           ++_compNum;
 | 
| deba@433 |    943 |         }
 | 
| deba@433 |    944 |       }
 | 
| deba@433 |    945 | 
 | 
| deba@433 |    946 |       void discover(const Arc& edge) {
 | 
| deba@433 |    947 |         _predMap.set(_graph.target(edge), edge);
 | 
| deba@433 |    948 |       }
 | 
| deba@433 |    949 | 
 | 
| deba@433 |    950 |       void examine(const Arc& edge) {
 | 
| deba@433 |    951 |         if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
 | 
| deba@433 |    952 |           return;
 | 
| deba@433 |    953 |         }
 | 
| deba@433 |    954 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |    955 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |    956 |         }
 | 
| deba@433 |    957 |       }
 | 
| deba@433 |    958 | 
 | 
| deba@433 |    959 |       void backtrack(const Arc& edge) {
 | 
| deba@433 |    960 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |    961 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |    962 |         }
 | 
| deba@433 |    963 |       }
 | 
| deba@433 |    964 | 
 | 
| deba@433 |    965 |     private:
 | 
| deba@433 |    966 |       const Digraph& _graph;
 | 
| deba@433 |    967 |       int& _compNum;
 | 
| deba@433 |    968 | 
 | 
| deba@433 |    969 |       typename Digraph::template NodeMap<int> _numMap;
 | 
| deba@433 |    970 |       typename Digraph::template NodeMap<int> _retMap;
 | 
| deba@433 |    971 |       typename Digraph::template NodeMap<Arc> _predMap;
 | 
| deba@433 |    972 |       int _num;
 | 
| deba@433 |    973 |     };
 | 
| deba@433 |    974 | 
 | 
| deba@433 |    975 |     template <typename Digraph, typename NodeMap>
 | 
| deba@433 |    976 |     class BiEdgeConnectedComponentsVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |    977 |     public:
 | 
| deba@433 |    978 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |    979 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |    980 |       typedef typename Digraph::Edge Edge;
 | 
| deba@433 |    981 | 
 | 
| deba@433 |    982 |       BiEdgeConnectedComponentsVisitor(const Digraph& graph,
 | 
| deba@433 |    983 |                                        NodeMap& compMap, int &compNum)
 | 
| deba@433 |    984 |         : _graph(graph), _compMap(compMap), _compNum(compNum),
 | 
| deba@433 |    985 |           _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 | 
| deba@433 |    986 | 
 | 
| deba@433 |    987 |       void start(const Node& node) {
 | 
| deba@433 |    988 |         _predMap.set(node, INVALID);
 | 
| deba@433 |    989 |       }
 | 
| deba@433 |    990 | 
 | 
| deba@433 |    991 |       void reach(const Node& node) {
 | 
| deba@433 |    992 |         _numMap.set(node, _num);
 | 
| deba@433 |    993 |         _retMap.set(node, _num);
 | 
| deba@433 |    994 |         _nodeStack.push(node);
 | 
| deba@433 |    995 |         ++_num;
 | 
| deba@433 |    996 |       }
 | 
| deba@433 |    997 | 
 | 
| deba@433 |    998 |       void leave(const Node& node) {
 | 
| deba@433 |    999 |         if (_numMap[node] <= _retMap[node]) {
 | 
| deba@433 |   1000 |           while (_nodeStack.top() != node) {
 | 
| deba@433 |   1001 |             _compMap.set(_nodeStack.top(), _compNum);
 | 
| deba@433 |   1002 |             _nodeStack.pop();
 | 
| deba@433 |   1003 |           }
 | 
| deba@433 |   1004 |           _compMap.set(node, _compNum);
 | 
| deba@433 |   1005 |           _nodeStack.pop();
 | 
| deba@433 |   1006 |           ++_compNum;
 | 
| deba@433 |   1007 |         }
 | 
| deba@433 |   1008 |       }
 | 
| deba@433 |   1009 | 
 | 
| deba@433 |   1010 |       void discover(const Arc& edge) {
 | 
| deba@433 |   1011 |         _predMap.set(_graph.target(edge), edge);
 | 
| deba@433 |   1012 |       }
 | 
| deba@433 |   1013 | 
 | 
| deba@433 |   1014 |       void examine(const Arc& edge) {
 | 
| deba@433 |   1015 |         if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
 | 
| deba@433 |   1016 |           return;
 | 
| deba@433 |   1017 |         }
 | 
| deba@433 |   1018 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |   1019 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |   1020 |         }
 | 
| deba@433 |   1021 |       }
 | 
| deba@433 |   1022 | 
 | 
| deba@433 |   1023 |       void backtrack(const Arc& edge) {
 | 
| deba@433 |   1024 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |   1025 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |   1026 |         }
 | 
| deba@433 |   1027 |       }
 | 
| deba@433 |   1028 | 
 | 
| deba@433 |   1029 |     private:
 | 
| deba@433 |   1030 |       const Digraph& _graph;
 | 
| deba@433 |   1031 |       NodeMap& _compMap;
 | 
| deba@433 |   1032 |       int& _compNum;
 | 
| deba@433 |   1033 | 
 | 
| deba@433 |   1034 |       typename Digraph::template NodeMap<int> _numMap;
 | 
| deba@433 |   1035 |       typename Digraph::template NodeMap<int> _retMap;
 | 
| deba@433 |   1036 |       typename Digraph::template NodeMap<Arc> _predMap;
 | 
| deba@433 |   1037 |       std::stack<Node> _nodeStack;
 | 
| deba@433 |   1038 |       int _num;
 | 
| deba@433 |   1039 |     };
 | 
| deba@433 |   1040 | 
 | 
| deba@433 |   1041 | 
 | 
| deba@433 |   1042 |     template <typename Digraph, typename ArcMap>
 | 
| deba@433 |   1043 |     class BiEdgeConnectedCutEdgesVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |   1044 |     public:
 | 
| deba@433 |   1045 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |   1046 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |   1047 |       typedef typename Digraph::Edge Edge;
 | 
| deba@433 |   1048 | 
 | 
| deba@433 |   1049 |       BiEdgeConnectedCutEdgesVisitor(const Digraph& graph,
 | 
| deba@433 |   1050 |                                      ArcMap& cutMap, int &cutNum)
 | 
| deba@433 |   1051 |         : _graph(graph), _cutMap(cutMap), _cutNum(cutNum),
 | 
| deba@433 |   1052 |           _numMap(graph), _retMap(graph), _predMap(graph), _num(0) {}
 | 
| deba@433 |   1053 | 
 | 
| deba@433 |   1054 |       void start(const Node& node) {
 | 
| deba@433 |   1055 |         _predMap[node] = INVALID;
 | 
| deba@433 |   1056 |       }
 | 
| deba@433 |   1057 | 
 | 
| deba@433 |   1058 |       void reach(const Node& node) {
 | 
| deba@433 |   1059 |         _numMap.set(node, _num);
 | 
| deba@433 |   1060 |         _retMap.set(node, _num);
 | 
| deba@433 |   1061 |         ++_num;
 | 
| deba@433 |   1062 |       }
 | 
| deba@433 |   1063 | 
 | 
| deba@433 |   1064 |       void leave(const Node& node) {
 | 
| deba@433 |   1065 |         if (_numMap[node] <= _retMap[node]) {
 | 
| deba@433 |   1066 |           if (_predMap[node] != INVALID) {
 | 
| deba@433 |   1067 |             _cutMap.set(_predMap[node], true);
 | 
| deba@433 |   1068 |             ++_cutNum;
 | 
| deba@433 |   1069 |           }
 | 
| deba@433 |   1070 |         }
 | 
| deba@433 |   1071 |       }
 | 
| deba@433 |   1072 | 
 | 
| deba@433 |   1073 |       void discover(const Arc& edge) {
 | 
| deba@433 |   1074 |         _predMap.set(_graph.target(edge), edge);
 | 
| deba@433 |   1075 |       }
 | 
| deba@433 |   1076 | 
 | 
| deba@433 |   1077 |       void examine(const Arc& edge) {
 | 
| deba@433 |   1078 |         if (_predMap[_graph.source(edge)] == _graph.oppositeArc(edge)) {
 | 
| deba@433 |   1079 |           return;
 | 
| deba@433 |   1080 |         }
 | 
| deba@433 |   1081 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |   1082 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |   1083 |         }
 | 
| deba@433 |   1084 |       }
 | 
| deba@433 |   1085 | 
 | 
| deba@433 |   1086 |       void backtrack(const Arc& edge) {
 | 
| deba@433 |   1087 |         if (_retMap[_graph.source(edge)] > _retMap[_graph.target(edge)]) {
 | 
| deba@433 |   1088 |           _retMap.set(_graph.source(edge), _retMap[_graph.target(edge)]);
 | 
| deba@433 |   1089 |         }
 | 
| deba@433 |   1090 |       }
 | 
| deba@433 |   1091 | 
 | 
| deba@433 |   1092 |     private:
 | 
| deba@433 |   1093 |       const Digraph& _graph;
 | 
| deba@433 |   1094 |       ArcMap& _cutMap;
 | 
| deba@433 |   1095 |       int& _cutNum;
 | 
| deba@433 |   1096 | 
 | 
| deba@433 |   1097 |       typename Digraph::template NodeMap<int> _numMap;
 | 
| deba@433 |   1098 |       typename Digraph::template NodeMap<int> _retMap;
 | 
| deba@433 |   1099 |       typename Digraph::template NodeMap<Arc> _predMap;
 | 
| deba@433 |   1100 |       int _num;
 | 
| deba@433 |   1101 |     };
 | 
| deba@433 |   1102 |   }
 | 
| deba@433 |   1103 | 
 | 
| deba@433 |   1104 |   template <typename Graph>
 | 
| deba@433 |   1105 |   int countBiEdgeConnectedComponents(const Graph& graph);
 | 
| deba@433 |   1106 | 
 | 
| kpeter@633 |   1107 |   /// \ingroup graph_properties
 | 
| deba@433 |   1108 |   ///
 | 
| kpeter@695 |   1109 |   /// \brief Check whether an undirected graph is bi-edge-connected.
 | 
| deba@433 |   1110 |   ///
 | 
| alpar@956 |   1111 |   /// This function checks whether the given undirected graph is
 | 
| kpeter@695 |   1112 |   /// bi-edge-connected, i.e. any two nodes are connected with at least
 | 
| kpeter@695 |   1113 |   /// two edge-disjoint paths.
 | 
| deba@433 |   1114 |   ///
 | 
| kpeter@695 |   1115 |   /// \return \c true if the graph is bi-edge-connected.
 | 
| kpeter@695 |   1116 |   /// \note By definition, the empty graph is bi-edge-connected.
 | 
| kpeter@695 |   1117 |   ///
 | 
| kpeter@695 |   1118 |   /// \see countBiEdgeConnectedComponents(), biEdgeConnectedComponents()
 | 
| deba@433 |   1119 |   template <typename Graph>
 | 
| deba@433 |   1120 |   bool biEdgeConnected(const Graph& graph) {
 | 
| deba@433 |   1121 |     return countBiEdgeConnectedComponents(graph) <= 1;
 | 
| deba@433 |   1122 |   }
 | 
| deba@433 |   1123 | 
 | 
| kpeter@633 |   1124 |   /// \ingroup graph_properties
 | 
| deba@433 |   1125 |   ///
 | 
| kpeter@695 |   1126 |   /// \brief Count the number of bi-edge-connected components of an
 | 
| kpeter@695 |   1127 |   /// undirected graph.
 | 
| deba@433 |   1128 |   ///
 | 
| kpeter@695 |   1129 |   /// This function counts the number of bi-edge-connected components of
 | 
| kpeter@695 |   1130 |   /// the given undirected graph.
 | 
| deba@433 |   1131 |   ///
 | 
| kpeter@695 |   1132 |   /// The bi-edge-connected components are the classes of an equivalence
 | 
| kpeter@695 |   1133 |   /// relation on the nodes of an undirected graph. Two nodes are in the
 | 
| kpeter@695 |   1134 |   /// same class if they are connected with at least two edge-disjoint
 | 
| kpeter@695 |   1135 |   /// paths.
 | 
| kpeter@695 |   1136 |   ///
 | 
| kpeter@695 |   1137 |   /// \return The number of bi-edge-connected components.
 | 
| kpeter@695 |   1138 |   ///
 | 
| kpeter@695 |   1139 |   /// \see biEdgeConnected(), biEdgeConnectedComponents()
 | 
| deba@433 |   1140 |   template <typename Graph>
 | 
| deba@433 |   1141 |   int countBiEdgeConnectedComponents(const Graph& graph) {
 | 
| deba@433 |   1142 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |   1143 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1144 | 
 | 
| deba@435 |   1145 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1146 | 
 | 
| deba@433 |   1147 |     typedef CountBiEdgeConnectedComponentsVisitor<Graph> Visitor;
 | 
| deba@433 |   1148 | 
 | 
| deba@433 |   1149 |     int compNum = 0;
 | 
| deba@433 |   1150 |     Visitor visitor(graph, compNum);
 | 
| deba@433 |   1151 | 
 | 
| deba@433 |   1152 |     DfsVisit<Graph, Visitor> dfs(graph, visitor);
 | 
| deba@433 |   1153 |     dfs.init();
 | 
| deba@433 |   1154 | 
 | 
| deba@433 |   1155 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1156 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1157 |         dfs.addSource(it);
 | 
| deba@433 |   1158 |         dfs.start();
 | 
| deba@433 |   1159 |       }
 | 
| deba@433 |   1160 |     }
 | 
| deba@433 |   1161 |     return compNum;
 | 
| deba@433 |   1162 |   }
 | 
| deba@433 |   1163 | 
 | 
| kpeter@633 |   1164 |   /// \ingroup graph_properties
 | 
| deba@433 |   1165 |   ///
 | 
| kpeter@695 |   1166 |   /// \brief Find the bi-edge-connected components of an undirected graph.
 | 
| deba@433 |   1167 |   ///
 | 
| kpeter@695 |   1168 |   /// This function finds the bi-edge-connected components of the given
 | 
| kpeter@695 |   1169 |   /// undirected graph.
 | 
| kpeter@695 |   1170 |   ///
 | 
| kpeter@695 |   1171 |   /// The bi-edge-connected components are the classes of an equivalence
 | 
| kpeter@695 |   1172 |   /// relation on the nodes of an undirected graph. Two nodes are in the
 | 
| kpeter@695 |   1173 |   /// same class if they are connected with at least two edge-disjoint
 | 
| kpeter@695 |   1174 |   /// paths.
 | 
| deba@433 |   1175 |   ///
 | 
| kpeter@633 |   1176 |   /// \image html edge_biconnected_components.png
 | 
| kpeter@633 |   1177 |   /// \image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
 | 
| kpeter@633 |   1178 |   ///
 | 
| kpeter@695 |   1179 |   /// \param graph The undirected graph.
 | 
| deba@433 |   1180 |   /// \retval compMap A writable node map. The values will be set from 0 to
 | 
| kpeter@695 |   1181 |   /// the number of the bi-edge-connected components minus one. Each value
 | 
| kpeter@695 |   1182 |   /// of the map will be set exactly once, and the values of a certain
 | 
| kpeter@695 |   1183 |   /// component will be set continuously.
 | 
| kpeter@695 |   1184 |   /// \return The number of bi-edge-connected components.
 | 
| kpeter@695 |   1185 |   ///
 | 
| kpeter@695 |   1186 |   /// \see biEdgeConnected(), countBiEdgeConnectedComponents()
 | 
| deba@433 |   1187 |   template <typename Graph, typename NodeMap>
 | 
| deba@433 |   1188 |   int biEdgeConnectedComponents(const Graph& graph, NodeMap& compMap) {
 | 
| deba@433 |   1189 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |   1190 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1191 |     typedef typename Graph::Node Node;
 | 
| deba@433 |   1192 |     checkConcept<concepts::WriteMap<Node, int>, NodeMap>();
 | 
| deba@433 |   1193 | 
 | 
| deba@435 |   1194 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1195 | 
 | 
| deba@433 |   1196 |     typedef BiEdgeConnectedComponentsVisitor<Graph, NodeMap> Visitor;
 | 
| deba@433 |   1197 | 
 | 
| deba@433 |   1198 |     int compNum = 0;
 | 
| deba@433 |   1199 |     Visitor visitor(graph, compMap, compNum);
 | 
| deba@433 |   1200 | 
 | 
| deba@433 |   1201 |     DfsVisit<Graph, Visitor> dfs(graph, visitor);
 | 
| deba@433 |   1202 |     dfs.init();
 | 
| deba@433 |   1203 | 
 | 
| deba@433 |   1204 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1205 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1206 |         dfs.addSource(it);
 | 
| deba@433 |   1207 |         dfs.start();
 | 
| deba@433 |   1208 |       }
 | 
| deba@433 |   1209 |     }
 | 
| deba@433 |   1210 |     return compNum;
 | 
| deba@433 |   1211 |   }
 | 
| deba@433 |   1212 | 
 | 
| kpeter@633 |   1213 |   /// \ingroup graph_properties
 | 
| deba@433 |   1214 |   ///
 | 
| kpeter@695 |   1215 |   /// \brief Find the bi-edge-connected cut edges in an undirected graph.
 | 
| deba@433 |   1216 |   ///
 | 
| kpeter@695 |   1217 |   /// This function finds the bi-edge-connected cut edges in the given
 | 
| alpar@956 |   1218 |   /// undirected graph.
 | 
| deba@433 |   1219 |   ///
 | 
| kpeter@695 |   1220 |   /// The bi-edge-connected components are the classes of an equivalence
 | 
| kpeter@695 |   1221 |   /// relation on the nodes of an undirected graph. Two nodes are in the
 | 
| kpeter@695 |   1222 |   /// same class if they are connected with at least two edge-disjoint
 | 
| kpeter@695 |   1223 |   /// paths.
 | 
| kpeter@695 |   1224 |   /// The bi-edge-connected components are separted by the cut edges of
 | 
| kpeter@695 |   1225 |   /// the components.
 | 
| kpeter@695 |   1226 |   ///
 | 
| kpeter@695 |   1227 |   /// \param graph The undirected graph.
 | 
| kpeter@695 |   1228 |   /// \retval cutMap A writable edge map. The values will be set to \c true
 | 
| kpeter@695 |   1229 |   /// for the cut edges (exactly once for each cut edge), and will not be
 | 
| kpeter@695 |   1230 |   /// changed for other edges.
 | 
| deba@433 |   1231 |   /// \return The number of cut edges.
 | 
| kpeter@695 |   1232 |   ///
 | 
| kpeter@695 |   1233 |   /// \see biEdgeConnected(), biEdgeConnectedComponents()
 | 
| deba@433 |   1234 |   template <typename Graph, typename EdgeMap>
 | 
| deba@433 |   1235 |   int biEdgeConnectedCutEdges(const Graph& graph, EdgeMap& cutMap) {
 | 
| deba@433 |   1236 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |   1237 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1238 |     typedef typename Graph::Edge Edge;
 | 
| deba@433 |   1239 |     checkConcept<concepts::WriteMap<Edge, bool>, EdgeMap>();
 | 
| deba@433 |   1240 | 
 | 
| deba@435 |   1241 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1242 | 
 | 
| deba@433 |   1243 |     typedef BiEdgeConnectedCutEdgesVisitor<Graph, EdgeMap> Visitor;
 | 
| deba@433 |   1244 | 
 | 
| deba@433 |   1245 |     int cutNum = 0;
 | 
| deba@433 |   1246 |     Visitor visitor(graph, cutMap, cutNum);
 | 
| deba@433 |   1247 | 
 | 
| deba@433 |   1248 |     DfsVisit<Graph, Visitor> dfs(graph, visitor);
 | 
| deba@433 |   1249 |     dfs.init();
 | 
| deba@433 |   1250 | 
 | 
| deba@433 |   1251 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1252 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1253 |         dfs.addSource(it);
 | 
| deba@433 |   1254 |         dfs.start();
 | 
| deba@433 |   1255 |       }
 | 
| deba@433 |   1256 |     }
 | 
| deba@433 |   1257 |     return cutNum;
 | 
| deba@433 |   1258 |   }
 | 
| deba@433 |   1259 | 
 | 
| deba@433 |   1260 | 
 | 
| deba@435 |   1261 |   namespace _connectivity_bits {
 | 
| deba@433 |   1262 | 
 | 
| deba@433 |   1263 |     template <typename Digraph, typename IntNodeMap>
 | 
| deba@433 |   1264 |     class TopologicalSortVisitor : public DfsVisitor<Digraph> {
 | 
| deba@433 |   1265 |     public:
 | 
| deba@433 |   1266 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |   1267 |       typedef typename Digraph::Arc edge;
 | 
| deba@433 |   1268 | 
 | 
| deba@433 |   1269 |       TopologicalSortVisitor(IntNodeMap& order, int num)
 | 
| deba@433 |   1270 |         : _order(order), _num(num) {}
 | 
| deba@433 |   1271 | 
 | 
| deba@433 |   1272 |       void leave(const Node& node) {
 | 
| deba@433 |   1273 |         _order.set(node, --_num);
 | 
| deba@433 |   1274 |       }
 | 
| deba@433 |   1275 | 
 | 
| deba@433 |   1276 |     private:
 | 
| deba@433 |   1277 |       IntNodeMap& _order;
 | 
| deba@433 |   1278 |       int _num;
 | 
| deba@433 |   1279 |     };
 | 
| deba@433 |   1280 | 
 | 
| deba@433 |   1281 |   }
 | 
| deba@433 |   1282 | 
 | 
| kpeter@633 |   1283 |   /// \ingroup graph_properties
 | 
| deba@433 |   1284 |   ///
 | 
| kpeter@695 |   1285 |   /// \brief Check whether a digraph is DAG.
 | 
| kpeter@695 |   1286 |   ///
 | 
| kpeter@695 |   1287 |   /// This function checks whether the given digraph is DAG, i.e.
 | 
| kpeter@695 |   1288 |   /// \e Directed \e Acyclic \e Graph.
 | 
| kpeter@695 |   1289 |   /// \return \c true if there is no directed cycle in the digraph.
 | 
| kpeter@695 |   1290 |   /// \see acyclic()
 | 
| kpeter@695 |   1291 |   template <typename Digraph>
 | 
| kpeter@695 |   1292 |   bool dag(const Digraph& digraph) {
 | 
| kpeter@695 |   1293 | 
 | 
| kpeter@695 |   1294 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| kpeter@695 |   1295 | 
 | 
| kpeter@695 |   1296 |     typedef typename Digraph::Node Node;
 | 
| kpeter@695 |   1297 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| kpeter@695 |   1298 |     typedef typename Digraph::Arc Arc;
 | 
| kpeter@695 |   1299 | 
 | 
| kpeter@695 |   1300 |     typedef typename Digraph::template NodeMap<bool> ProcessedMap;
 | 
| kpeter@695 |   1301 | 
 | 
| kpeter@695 |   1302 |     typename Dfs<Digraph>::template SetProcessedMap<ProcessedMap>::
 | 
| kpeter@695 |   1303 |       Create dfs(digraph);
 | 
| kpeter@695 |   1304 | 
 | 
| kpeter@695 |   1305 |     ProcessedMap processed(digraph);
 | 
| kpeter@695 |   1306 |     dfs.processedMap(processed);
 | 
| kpeter@695 |   1307 | 
 | 
| kpeter@695 |   1308 |     dfs.init();
 | 
| kpeter@695 |   1309 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| kpeter@695 |   1310 |       if (!dfs.reached(it)) {
 | 
| kpeter@695 |   1311 |         dfs.addSource(it);
 | 
| kpeter@695 |   1312 |         while (!dfs.emptyQueue()) {
 | 
| kpeter@695 |   1313 |           Arc arc = dfs.nextArc();
 | 
| kpeter@695 |   1314 |           Node target = digraph.target(arc);
 | 
| kpeter@695 |   1315 |           if (dfs.reached(target) && !processed[target]) {
 | 
| kpeter@695 |   1316 |             return false;
 | 
| kpeter@695 |   1317 |           }
 | 
| kpeter@695 |   1318 |           dfs.processNextArc();
 | 
| kpeter@695 |   1319 |         }
 | 
| kpeter@695 |   1320 |       }
 | 
| kpeter@695 |   1321 |     }
 | 
| kpeter@695 |   1322 |     return true;
 | 
| kpeter@695 |   1323 |   }
 | 
| kpeter@695 |   1324 | 
 | 
| kpeter@695 |   1325 |   /// \ingroup graph_properties
 | 
| kpeter@695 |   1326 |   ///
 | 
| deba@433 |   1327 |   /// \brief Sort the nodes of a DAG into topolgical order.
 | 
| deba@433 |   1328 |   ///
 | 
| kpeter@695 |   1329 |   /// This function sorts the nodes of the given acyclic digraph (DAG)
 | 
| kpeter@695 |   1330 |   /// into topolgical order.
 | 
| deba@433 |   1331 |   ///
 | 
| kpeter@695 |   1332 |   /// \param digraph The digraph, which must be DAG.
 | 
| deba@433 |   1333 |   /// \retval order A writable node map. The values will be set from 0 to
 | 
| kpeter@695 |   1334 |   /// the number of the nodes in the digraph minus one. Each value of the
 | 
| kpeter@695 |   1335 |   /// map will be set exactly once, and the values will be set descending
 | 
| kpeter@695 |   1336 |   /// order.
 | 
| deba@433 |   1337 |   ///
 | 
| kpeter@695 |   1338 |   /// \see dag(), checkedTopologicalSort()
 | 
| deba@433 |   1339 |   template <typename Digraph, typename NodeMap>
 | 
| kpeter@695 |   1340 |   void topologicalSort(const Digraph& digraph, NodeMap& order) {
 | 
| deba@435 |   1341 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1342 | 
 | 
| deba@433 |   1343 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| deba@433 |   1344 |     checkConcept<concepts::WriteMap<typename Digraph::Node, int>, NodeMap>();
 | 
| deba@433 |   1345 | 
 | 
| deba@433 |   1346 |     typedef typename Digraph::Node Node;
 | 
| deba@433 |   1347 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| deba@433 |   1348 |     typedef typename Digraph::Arc Arc;
 | 
| deba@433 |   1349 | 
 | 
| deba@433 |   1350 |     TopologicalSortVisitor<Digraph, NodeMap>
 | 
| kpeter@695 |   1351 |       visitor(order, countNodes(digraph));
 | 
| deba@433 |   1352 | 
 | 
| deba@433 |   1353 |     DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
 | 
| kpeter@695 |   1354 |       dfs(digraph, visitor);
 | 
| deba@433 |   1355 | 
 | 
| deba@433 |   1356 |     dfs.init();
 | 
| kpeter@695 |   1357 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@433 |   1358 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1359 |         dfs.addSource(it);
 | 
| deba@433 |   1360 |         dfs.start();
 | 
| deba@433 |   1361 |       }
 | 
| deba@433 |   1362 |     }
 | 
| deba@433 |   1363 |   }
 | 
| deba@433 |   1364 | 
 | 
| kpeter@633 |   1365 |   /// \ingroup graph_properties
 | 
| deba@433 |   1366 |   ///
 | 
| deba@433 |   1367 |   /// \brief Sort the nodes of a DAG into topolgical order.
 | 
| deba@433 |   1368 |   ///
 | 
| kpeter@695 |   1369 |   /// This function sorts the nodes of the given acyclic digraph (DAG)
 | 
| kpeter@695 |   1370 |   /// into topolgical order and also checks whether the given digraph
 | 
| kpeter@695 |   1371 |   /// is DAG.
 | 
| deba@433 |   1372 |   ///
 | 
| kpeter@695 |   1373 |   /// \param digraph The digraph.
 | 
| kpeter@695 |   1374 |   /// \retval order A readable and writable node map. The values will be
 | 
| alpar@956 |   1375 |   /// set from 0 to the number of the nodes in the digraph minus one.
 | 
| kpeter@695 |   1376 |   /// Each value of the map will be set exactly once, and the values will
 | 
| kpeter@695 |   1377 |   /// be set descending order.
 | 
| kpeter@695 |   1378 |   /// \return \c false if the digraph is not DAG.
 | 
| deba@433 |   1379 |   ///
 | 
| kpeter@695 |   1380 |   /// \see dag(), topologicalSort()
 | 
| deba@433 |   1381 |   template <typename Digraph, typename NodeMap>
 | 
| deba@435 |   1382 |   bool checkedTopologicalSort(const Digraph& digraph, NodeMap& order) {
 | 
| deba@435 |   1383 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1384 | 
 | 
| deba@433 |   1385 |     checkConcept<concepts::Digraph, Digraph>();
 | 
| deba@433 |   1386 |     checkConcept<concepts::ReadWriteMap<typename Digraph::Node, int>,
 | 
| deba@433 |   1387 |       NodeMap>();
 | 
| deba@433 |   1388 | 
 | 
| deba@433 |   1389 |     typedef typename Digraph::Node Node;
 | 
| deba@433 |   1390 |     typedef typename Digraph::NodeIt NodeIt;
 | 
| deba@433 |   1391 |     typedef typename Digraph::Arc Arc;
 | 
| deba@433 |   1392 | 
 | 
| deba@435 |   1393 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@435 |   1394 |       order.set(it, -1);
 | 
| deba@435 |   1395 |     }
 | 
| deba@433 |   1396 | 
 | 
| deba@433 |   1397 |     TopologicalSortVisitor<Digraph, NodeMap>
 | 
| deba@435 |   1398 |       visitor(order, countNodes(digraph));
 | 
| deba@433 |   1399 | 
 | 
| deba@433 |   1400 |     DfsVisit<Digraph, TopologicalSortVisitor<Digraph, NodeMap> >
 | 
| deba@435 |   1401 |       dfs(digraph, visitor);
 | 
| deba@433 |   1402 | 
 | 
| deba@433 |   1403 |     dfs.init();
 | 
| deba@435 |   1404 |     for (NodeIt it(digraph); it != INVALID; ++it) {
 | 
| deba@433 |   1405 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1406 |         dfs.addSource(it);
 | 
| deba@433 |   1407 |         while (!dfs.emptyQueue()) {
 | 
| deba@435 |   1408 |            Arc arc = dfs.nextArc();
 | 
| deba@435 |   1409 |            Node target = digraph.target(arc);
 | 
| deba@433 |   1410 |            if (dfs.reached(target) && order[target] == -1) {
 | 
| deba@433 |   1411 |              return false;
 | 
| deba@433 |   1412 |            }
 | 
| deba@433 |   1413 |            dfs.processNextArc();
 | 
| deba@433 |   1414 |          }
 | 
| deba@433 |   1415 |       }
 | 
| deba@433 |   1416 |     }
 | 
| deba@433 |   1417 |     return true;
 | 
| deba@433 |   1418 |   }
 | 
| deba@433 |   1419 | 
 | 
| kpeter@633 |   1420 |   /// \ingroup graph_properties
 | 
| deba@433 |   1421 |   ///
 | 
| kpeter@695 |   1422 |   /// \brief Check whether an undirected graph is acyclic.
 | 
| deba@433 |   1423 |   ///
 | 
| kpeter@695 |   1424 |   /// This function checks whether the given undirected graph is acyclic.
 | 
| kpeter@695 |   1425 |   /// \return \c true if there is no cycle in the graph.
 | 
| kpeter@695 |   1426 |   /// \see dag()
 | 
| deba@433 |   1427 |   template <typename Graph>
 | 
| deba@433 |   1428 |   bool acyclic(const Graph& graph) {
 | 
| deba@433 |   1429 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |   1430 |     typedef typename Graph::Node Node;
 | 
| deba@433 |   1431 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1432 |     typedef typename Graph::Arc Arc;
 | 
| deba@433 |   1433 |     Dfs<Graph> dfs(graph);
 | 
| deba@433 |   1434 |     dfs.init();
 | 
| deba@433 |   1435 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1436 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1437 |         dfs.addSource(it);
 | 
| deba@433 |   1438 |         while (!dfs.emptyQueue()) {
 | 
| kpeter@695 |   1439 |           Arc arc = dfs.nextArc();
 | 
| kpeter@695 |   1440 |           Node source = graph.source(arc);
 | 
| kpeter@695 |   1441 |           Node target = graph.target(arc);
 | 
| deba@433 |   1442 |           if (dfs.reached(target) &&
 | 
| kpeter@695 |   1443 |               dfs.predArc(source) != graph.oppositeArc(arc)) {
 | 
| deba@433 |   1444 |             return false;
 | 
| deba@433 |   1445 |           }
 | 
| deba@433 |   1446 |           dfs.processNextArc();
 | 
| deba@433 |   1447 |         }
 | 
| deba@433 |   1448 |       }
 | 
| deba@433 |   1449 |     }
 | 
| deba@433 |   1450 |     return true;
 | 
| deba@433 |   1451 |   }
 | 
| deba@433 |   1452 | 
 | 
| kpeter@633 |   1453 |   /// \ingroup graph_properties
 | 
| deba@433 |   1454 |   ///
 | 
| kpeter@695 |   1455 |   /// \brief Check whether an undirected graph is tree.
 | 
| deba@433 |   1456 |   ///
 | 
| kpeter@695 |   1457 |   /// This function checks whether the given undirected graph is tree.
 | 
| kpeter@695 |   1458 |   /// \return \c true if the graph is acyclic and connected.
 | 
| kpeter@695 |   1459 |   /// \see acyclic(), connected()
 | 
| deba@433 |   1460 |   template <typename Graph>
 | 
| deba@433 |   1461 |   bool tree(const Graph& graph) {
 | 
| deba@433 |   1462 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |   1463 |     typedef typename Graph::Node Node;
 | 
| deba@433 |   1464 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1465 |     typedef typename Graph::Arc Arc;
 | 
| kpeter@694 |   1466 |     if (NodeIt(graph) == INVALID) return true;
 | 
| deba@433 |   1467 |     Dfs<Graph> dfs(graph);
 | 
| deba@433 |   1468 |     dfs.init();
 | 
| deba@433 |   1469 |     dfs.addSource(NodeIt(graph));
 | 
| deba@433 |   1470 |     while (!dfs.emptyQueue()) {
 | 
| kpeter@695 |   1471 |       Arc arc = dfs.nextArc();
 | 
| kpeter@695 |   1472 |       Node source = graph.source(arc);
 | 
| kpeter@695 |   1473 |       Node target = graph.target(arc);
 | 
| deba@433 |   1474 |       if (dfs.reached(target) &&
 | 
| kpeter@695 |   1475 |           dfs.predArc(source) != graph.oppositeArc(arc)) {
 | 
| deba@433 |   1476 |         return false;
 | 
| deba@433 |   1477 |       }
 | 
| deba@433 |   1478 |       dfs.processNextArc();
 | 
| deba@433 |   1479 |     }
 | 
| deba@433 |   1480 |     for (NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1481 |       if (!dfs.reached(it)) {
 | 
| deba@433 |   1482 |         return false;
 | 
| deba@433 |   1483 |       }
 | 
| deba@433 |   1484 |     }
 | 
| deba@433 |   1485 |     return true;
 | 
| deba@433 |   1486 |   }
 | 
| deba@433 |   1487 | 
 | 
| deba@435 |   1488 |   namespace _connectivity_bits {
 | 
| deba@433 |   1489 | 
 | 
| deba@433 |   1490 |     template <typename Digraph>
 | 
| deba@433 |   1491 |     class BipartiteVisitor : public BfsVisitor<Digraph> {
 | 
| deba@433 |   1492 |     public:
 | 
| deba@433 |   1493 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |   1494 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |   1495 | 
 | 
| deba@433 |   1496 |       BipartiteVisitor(const Digraph& graph, bool& bipartite)
 | 
| deba@433 |   1497 |         : _graph(graph), _part(graph), _bipartite(bipartite) {}
 | 
| deba@433 |   1498 | 
 | 
| deba@433 |   1499 |       void start(const Node& node) {
 | 
| deba@433 |   1500 |         _part[node] = true;
 | 
| deba@433 |   1501 |       }
 | 
| deba@433 |   1502 |       void discover(const Arc& edge) {
 | 
| deba@433 |   1503 |         _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
 | 
| deba@433 |   1504 |       }
 | 
| deba@433 |   1505 |       void examine(const Arc& edge) {
 | 
| deba@433 |   1506 |         _bipartite = _bipartite &&
 | 
| deba@433 |   1507 |           _part[_graph.target(edge)] != _part[_graph.source(edge)];
 | 
| deba@433 |   1508 |       }
 | 
| deba@433 |   1509 | 
 | 
| deba@433 |   1510 |     private:
 | 
| deba@433 |   1511 | 
 | 
| deba@433 |   1512 |       const Digraph& _graph;
 | 
| deba@433 |   1513 |       typename Digraph::template NodeMap<bool> _part;
 | 
| deba@433 |   1514 |       bool& _bipartite;
 | 
| deba@433 |   1515 |     };
 | 
| deba@433 |   1516 | 
 | 
| deba@433 |   1517 |     template <typename Digraph, typename PartMap>
 | 
| deba@433 |   1518 |     class BipartitePartitionsVisitor : public BfsVisitor<Digraph> {
 | 
| deba@433 |   1519 |     public:
 | 
| deba@433 |   1520 |       typedef typename Digraph::Arc Arc;
 | 
| deba@433 |   1521 |       typedef typename Digraph::Node Node;
 | 
| deba@433 |   1522 | 
 | 
| deba@433 |   1523 |       BipartitePartitionsVisitor(const Digraph& graph,
 | 
| deba@433 |   1524 |                                  PartMap& part, bool& bipartite)
 | 
| deba@433 |   1525 |         : _graph(graph), _part(part), _bipartite(bipartite) {}
 | 
| deba@433 |   1526 | 
 | 
| deba@433 |   1527 |       void start(const Node& node) {
 | 
| deba@433 |   1528 |         _part.set(node, true);
 | 
| deba@433 |   1529 |       }
 | 
| deba@433 |   1530 |       void discover(const Arc& edge) {
 | 
| deba@433 |   1531 |         _part.set(_graph.target(edge), !_part[_graph.source(edge)]);
 | 
| deba@433 |   1532 |       }
 | 
| deba@433 |   1533 |       void examine(const Arc& edge) {
 | 
| deba@433 |   1534 |         _bipartite = _bipartite &&
 | 
| deba@433 |   1535 |           _part[_graph.target(edge)] != _part[_graph.source(edge)];
 | 
| deba@433 |   1536 |       }
 | 
| deba@433 |   1537 | 
 | 
| deba@433 |   1538 |     private:
 | 
| deba@433 |   1539 | 
 | 
| deba@433 |   1540 |       const Digraph& _graph;
 | 
| deba@433 |   1541 |       PartMap& _part;
 | 
| deba@433 |   1542 |       bool& _bipartite;
 | 
| deba@433 |   1543 |     };
 | 
| deba@433 |   1544 |   }
 | 
| deba@433 |   1545 | 
 | 
| kpeter@633 |   1546 |   /// \ingroup graph_properties
 | 
| deba@433 |   1547 |   ///
 | 
| kpeter@695 |   1548 |   /// \brief Check whether an undirected graph is bipartite.
 | 
| deba@433 |   1549 |   ///
 | 
| kpeter@695 |   1550 |   /// The function checks whether the given undirected graph is bipartite.
 | 
| kpeter@695 |   1551 |   /// \return \c true if the graph is bipartite.
 | 
| kpeter@695 |   1552 |   ///
 | 
| kpeter@695 |   1553 |   /// \see bipartitePartitions()
 | 
| deba@433 |   1554 |   template<typename Graph>
 | 
| kpeter@695 |   1555 |   bool bipartite(const Graph &graph){
 | 
| deba@435 |   1556 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1557 | 
 | 
| deba@433 |   1558 |     checkConcept<concepts::Graph, Graph>();
 | 
| deba@433 |   1559 | 
 | 
| deba@433 |   1560 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1561 |     typedef typename Graph::ArcIt ArcIt;
 | 
| deba@433 |   1562 | 
 | 
| deba@433 |   1563 |     bool bipartite = true;
 | 
| deba@433 |   1564 | 
 | 
| deba@433 |   1565 |     BipartiteVisitor<Graph>
 | 
| deba@433 |   1566 |       visitor(graph, bipartite);
 | 
| deba@433 |   1567 |     BfsVisit<Graph, BipartiteVisitor<Graph> >
 | 
| deba@433 |   1568 |       bfs(graph, visitor);
 | 
| deba@433 |   1569 |     bfs.init();
 | 
| deba@433 |   1570 |     for(NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1571 |       if(!bfs.reached(it)){
 | 
| deba@433 |   1572 |         bfs.addSource(it);
 | 
| deba@433 |   1573 |         while (!bfs.emptyQueue()) {
 | 
| deba@433 |   1574 |           bfs.processNextNode();
 | 
| deba@433 |   1575 |           if (!bipartite) return false;
 | 
| deba@433 |   1576 |         }
 | 
| deba@433 |   1577 |       }
 | 
| deba@433 |   1578 |     }
 | 
| deba@433 |   1579 |     return true;
 | 
| deba@433 |   1580 |   }
 | 
| deba@433 |   1581 | 
 | 
| kpeter@633 |   1582 |   /// \ingroup graph_properties
 | 
| deba@433 |   1583 |   ///
 | 
| kpeter@695 |   1584 |   /// \brief Find the bipartite partitions of an undirected graph.
 | 
| deba@433 |   1585 |   ///
 | 
| kpeter@695 |   1586 |   /// This function checks whether the given undirected graph is bipartite
 | 
| kpeter@695 |   1587 |   /// and gives back the bipartite partitions.
 | 
| kpeter@633 |   1588 |   ///
 | 
| kpeter@633 |   1589 |   /// \image html bipartite_partitions.png
 | 
| kpeter@633 |   1590 |   /// \image latex bipartite_partitions.eps "Bipartite partititions" width=\textwidth
 | 
| kpeter@633 |   1591 |   ///
 | 
| deba@433 |   1592 |   /// \param graph The undirected graph.
 | 
| kpeter@695 |   1593 |   /// \retval partMap A writable node map of \c bool (or convertible) value
 | 
| kpeter@695 |   1594 |   /// type. The values will be set to \c true for one component and
 | 
| kpeter@695 |   1595 |   /// \c false for the other one.
 | 
| kpeter@695 |   1596 |   /// \return \c true if the graph is bipartite, \c false otherwise.
 | 
| kpeter@695 |   1597 |   ///
 | 
| kpeter@695 |   1598 |   /// \see bipartite()
 | 
| deba@433 |   1599 |   template<typename Graph, typename NodeMap>
 | 
| kpeter@695 |   1600 |   bool bipartitePartitions(const Graph &graph, NodeMap &partMap){
 | 
| deba@435 |   1601 |     using namespace _connectivity_bits;
 | 
| deba@433 |   1602 | 
 | 
| deba@433 |   1603 |     checkConcept<concepts::Graph, Graph>();
 | 
| kpeter@695 |   1604 |     checkConcept<concepts::WriteMap<typename Graph::Node, bool>, NodeMap>();
 | 
| deba@433 |   1605 | 
 | 
| deba@433 |   1606 |     typedef typename Graph::Node Node;
 | 
| deba@433 |   1607 |     typedef typename Graph::NodeIt NodeIt;
 | 
| deba@433 |   1608 |     typedef typename Graph::ArcIt ArcIt;
 | 
| deba@433 |   1609 | 
 | 
| deba@433 |   1610 |     bool bipartite = true;
 | 
| deba@433 |   1611 | 
 | 
| deba@433 |   1612 |     BipartitePartitionsVisitor<Graph, NodeMap>
 | 
| deba@433 |   1613 |       visitor(graph, partMap, bipartite);
 | 
| deba@433 |   1614 |     BfsVisit<Graph, BipartitePartitionsVisitor<Graph, NodeMap> >
 | 
| deba@433 |   1615 |       bfs(graph, visitor);
 | 
| deba@433 |   1616 |     bfs.init();
 | 
| deba@433 |   1617 |     for(NodeIt it(graph); it != INVALID; ++it) {
 | 
| deba@433 |   1618 |       if(!bfs.reached(it)){
 | 
| deba@433 |   1619 |         bfs.addSource(it);
 | 
| deba@433 |   1620 |         while (!bfs.emptyQueue()) {
 | 
| deba@433 |   1621 |           bfs.processNextNode();
 | 
| deba@433 |   1622 |           if (!bipartite) return false;
 | 
| deba@433 |   1623 |         }
 | 
| deba@433 |   1624 |       }
 | 
| deba@433 |   1625 |     }
 | 
| deba@433 |   1626 |     return true;
 | 
| deba@433 |   1627 |   }
 | 
| deba@433 |   1628 | 
 | 
| kpeter@695 |   1629 |   /// \ingroup graph_properties
 | 
| deba@433 |   1630 |   ///
 | 
| kpeter@695 |   1631 |   /// \brief Check whether the given graph contains no loop arcs/edges.
 | 
| kpeter@695 |   1632 |   ///
 | 
| kpeter@695 |   1633 |   /// This function returns \c true if there are no loop arcs/edges in
 | 
| kpeter@695 |   1634 |   /// the given graph. It works for both directed and undirected graphs.
 | 
| kpeter@695 |   1635 |   template <typename Graph>
 | 
| kpeter@695 |   1636 |   bool loopFree(const Graph& graph) {
 | 
| kpeter@695 |   1637 |     for (typename Graph::ArcIt it(graph); it != INVALID; ++it) {
 | 
| kpeter@695 |   1638 |       if (graph.source(it) == graph.target(it)) return false;
 | 
| deba@433 |   1639 |     }
 | 
| deba@433 |   1640 |     return true;
 | 
| deba@433 |   1641 |   }
 | 
| deba@433 |   1642 | 
 | 
| kpeter@695 |   1643 |   /// \ingroup graph_properties
 | 
| deba@433 |   1644 |   ///
 | 
| kpeter@695 |   1645 |   /// \brief Check whether the given graph contains no parallel arcs/edges.
 | 
| kpeter@695 |   1646 |   ///
 | 
| kpeter@695 |   1647 |   /// This function returns \c true if there are no parallel arcs/edges in
 | 
| kpeter@695 |   1648 |   /// the given graph. It works for both directed and undirected graphs.
 | 
| kpeter@694 |   1649 |   template <typename Graph>
 | 
| kpeter@694 |   1650 |   bool parallelFree(const Graph& graph) {
 | 
| kpeter@694 |   1651 |     typename Graph::template NodeMap<int> reached(graph, 0);
 | 
| kpeter@694 |   1652 |     int cnt = 1;
 | 
| kpeter@694 |   1653 |     for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 | 
| kpeter@694 |   1654 |       for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
 | 
| kpeter@694 |   1655 |         if (reached[graph.target(a)] == cnt) return false;
 | 
| kpeter@694 |   1656 |         reached[graph.target(a)] = cnt;
 | 
| deba@433 |   1657 |       }
 | 
| kpeter@694 |   1658 |       ++cnt;
 | 
| deba@433 |   1659 |     }
 | 
| deba@433 |   1660 |     return true;
 | 
| deba@433 |   1661 |   }
 | 
| deba@433 |   1662 | 
 | 
| kpeter@695 |   1663 |   /// \ingroup graph_properties
 | 
| deba@433 |   1664 |   ///
 | 
| kpeter@695 |   1665 |   /// \brief Check whether the given graph is simple.
 | 
| kpeter@695 |   1666 |   ///
 | 
| kpeter@695 |   1667 |   /// This function returns \c true if the given graph is simple, i.e.
 | 
| kpeter@695 |   1668 |   /// it contains no loop arcs/edges and no parallel arcs/edges.
 | 
| kpeter@695 |   1669 |   /// The function works for both directed and undirected graphs.
 | 
| kpeter@695 |   1670 |   /// \see loopFree(), parallelFree()
 | 
| kpeter@694 |   1671 |   template <typename Graph>
 | 
| kpeter@694 |   1672 |   bool simpleGraph(const Graph& graph) {
 | 
| kpeter@694 |   1673 |     typename Graph::template NodeMap<int> reached(graph, 0);
 | 
| kpeter@694 |   1674 |     int cnt = 1;
 | 
| kpeter@694 |   1675 |     for (typename Graph::NodeIt n(graph); n != INVALID; ++n) {
 | 
| kpeter@694 |   1676 |       reached[n] = cnt;
 | 
| kpeter@694 |   1677 |       for (typename Graph::OutArcIt a(graph, n); a != INVALID; ++a) {
 | 
| kpeter@694 |   1678 |         if (reached[graph.target(a)] == cnt) return false;
 | 
| kpeter@694 |   1679 |         reached[graph.target(a)] = cnt;
 | 
| deba@433 |   1680 |       }
 | 
| kpeter@694 |   1681 |       ++cnt;
 | 
| deba@433 |   1682 |     }
 | 
| deba@433 |   1683 |     return true;
 | 
| deba@433 |   1684 |   }
 | 
| deba@433 |   1685 | 
 | 
| deba@433 |   1686 | } //namespace lemon
 | 
| deba@433 |   1687 | 
 | 
| deba@435 |   1688 | #endif //LEMON_CONNECTIVITY_H
 |