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