| 
     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  |