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