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