lemon/dfs.h
author deba
Thu, 24 Nov 2005 15:48:53 +0000
changeset 1832 d0c28d9c9141
parent 1773 ea5927cef15c
child 1865 dcefd1d1377f
permissions -rw-r--r--
Bug fix
     1 /* -*- C++ -*-
     2  * lemon/dfs.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_DFS_H
    18 #define LEMON_DFS_H
    19 
    20 ///\ingroup flowalgs
    21 ///\file
    22 ///\brief Dfs algorithm.
    23 
    24 #include <lemon/list_graph.h>
    25 #include <lemon/graph_utils.h>
    26 #include <lemon/invalid.h>
    27 #include <lemon/error.h>
    28 #include <lemon/maps.h>
    29 
    30 #include <lemon/concept_check.h>
    31 
    32 namespace lemon {
    33 
    34   
    35   ///Default traits class of Dfs class.
    36 
    37   ///Default traits class of Dfs class.
    38   ///\param GR Graph type.
    39   template<class GR>
    40   struct DfsDefaultTraits
    41   {
    42     ///The graph type the algorithm runs on. 
    43     typedef GR Graph;
    44     ///\brief The type of the map that stores the last
    45     ///edges of the %DFS paths.
    46     /// 
    47     ///The type of the map that stores the last
    48     ///edges of the %DFS paths.
    49     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    50     ///
    51     typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
    52     ///Instantiates a PredMap.
    53  
    54     ///This function instantiates a \ref PredMap. 
    55     ///\param G is the graph, to which we would like to define the PredMap.
    56     ///\todo The graph alone may be insufficient to initialize
    57     static PredMap *createPredMap(const GR &G) 
    58     {
    59       return new PredMap(G);
    60     }
    61 
    62     ///The type of the map that indicates which nodes are processed.
    63  
    64     ///The type of the map that indicates which nodes are processed.
    65     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    66     ///\todo named parameter to set this type, function to read and write.
    67     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
    68     ///Instantiates a ProcessedMap.
    69  
    70     ///This function instantiates a \ref ProcessedMap. 
    71     ///\param g is the graph, to which
    72     ///we would like to define the \ref ProcessedMap
    73 #ifdef DOXYGEN
    74     static ProcessedMap *createProcessedMap(const GR &g)
    75 #else
    76     static ProcessedMap *createProcessedMap(const GR &)
    77 #endif
    78     {
    79       return new ProcessedMap();
    80     }
    81     ///The type of the map that indicates which nodes are reached.
    82  
    83     ///The type of the map that indicates which nodes are reached.
    84     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    85     ///\todo named parameter to set this type, function to read and write.
    86     typedef typename Graph::template NodeMap<bool> ReachedMap;
    87     ///Instantiates a ReachedMap.
    88  
    89     ///This function instantiates a \ref ReachedMap. 
    90     ///\param G is the graph, to which
    91     ///we would like to define the \ref ReachedMap.
    92     static ReachedMap *createReachedMap(const GR &G)
    93     {
    94       return new ReachedMap(G);
    95     }
    96     ///The type of the map that stores the dists of the nodes.
    97  
    98     ///The type of the map that stores the dists of the nodes.
    99     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   100     ///
   101     typedef typename Graph::template NodeMap<int> DistMap;
   102     ///Instantiates a DistMap.
   103  
   104     ///This function instantiates a \ref DistMap. 
   105     ///\param G is the graph, to which we would like to define the \ref DistMap
   106     static DistMap *createDistMap(const GR &G)
   107     {
   108       return new DistMap(G);
   109     }
   110   };
   111   
   112   ///%DFS algorithm class.
   113   
   114   ///\ingroup flowalgs
   115   ///This class provides an efficient implementation of the %DFS algorithm.
   116   ///
   117   ///\param GR The graph type the algorithm runs on. The default value is
   118   ///\ref ListGraph. The value of GR is not used directly by Dfs, it
   119   ///is only passed to \ref DfsDefaultTraits.
   120   ///\param TR Traits class to set various data types used by the algorithm.
   121   ///The default traits class is
   122   ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
   123   ///See \ref DfsDefaultTraits for the documentation of
   124   ///a Dfs traits class.
   125   ///
   126   ///\author Jacint Szabo and Alpar Juttner
   127 #ifdef DOXYGEN
   128   template <typename GR,
   129 	    typename TR>
   130 #else
   131   template <typename GR=ListGraph,
   132 	    typename TR=DfsDefaultTraits<GR> >
   133 #endif
   134   class Dfs {
   135   public:
   136     /**
   137      * \brief \ref Exception for uninitialized parameters.
   138      *
   139      * This error represents problems in the initialization
   140      * of the parameters of the algorithms.
   141      */
   142     class UninitializedParameter : public lemon::UninitializedParameter {
   143     public:
   144       virtual const char* exceptionName() const {
   145 	return "lemon::Dfs::UninitializedParameter";
   146       }
   147     };
   148 
   149     typedef TR Traits;
   150     ///The type of the underlying graph.
   151     typedef typename TR::Graph Graph;
   152     ///\e
   153     typedef typename Graph::Node Node;
   154     ///\e
   155     typedef typename Graph::NodeIt NodeIt;
   156     ///\e
   157     typedef typename Graph::Edge Edge;
   158     ///\e
   159     typedef typename Graph::OutEdgeIt OutEdgeIt;
   160     
   161     ///\brief The type of the map that stores the last
   162     ///edges of the %DFS paths.
   163     typedef typename TR::PredMap PredMap;
   164     ///The type of the map indicating which nodes are reached.
   165     typedef typename TR::ReachedMap ReachedMap;
   166     ///The type of the map indicating which nodes are processed.
   167     typedef typename TR::ProcessedMap ProcessedMap;
   168     ///The type of the map that stores the dists of the nodes.
   169     typedef typename TR::DistMap DistMap;
   170   private:
   171     /// Pointer to the underlying graph.
   172     const Graph *G;
   173     ///Pointer to the map of predecessors edges.
   174     PredMap *_pred;
   175     ///Indicates if \ref _pred is locally allocated (\c true) or not.
   176     bool local_pred;
   177     ///Pointer to the map of distances.
   178     DistMap *_dist;
   179     ///Indicates if \ref _dist is locally allocated (\c true) or not.
   180     bool local_dist;
   181     ///Pointer to the map of reached status of the nodes.
   182     ReachedMap *_reached;
   183     ///Indicates if \ref _reached is locally allocated (\c true) or not.
   184     bool local_reached;
   185     ///Pointer to the map of processed status of the nodes.
   186     ProcessedMap *_processed;
   187     ///Indicates if \ref _processed is locally allocated (\c true) or not.
   188     bool local_processed;
   189 
   190     std::vector<typename Graph::OutEdgeIt> _stack;
   191     int _stack_head;
   192 
   193     ///Creates the maps if necessary.
   194     
   195     ///\todo Better memory allocation (instead of new).
   196     void create_maps() 
   197     {
   198       if(!_pred) {
   199 	local_pred = true;
   200 	_pred = Traits::createPredMap(*G);
   201       }
   202       if(!_dist) {
   203 	local_dist = true;
   204 	_dist = Traits::createDistMap(*G);
   205       }
   206       if(!_reached) {
   207 	local_reached = true;
   208 	_reached = Traits::createReachedMap(*G);
   209       }
   210       if(!_processed) {
   211 	local_processed = true;
   212 	_processed = Traits::createProcessedMap(*G);
   213       }
   214     }
   215 
   216   protected:
   217 
   218     Dfs() {}
   219     
   220   public:
   221 
   222     typedef Dfs Create;
   223 
   224     ///\name Named template parameters
   225 
   226     ///@{
   227 
   228     template <class T>
   229     struct DefPredMapTraits : public Traits {
   230       typedef T PredMap;
   231       static PredMap *createPredMap(const Graph &G) 
   232       {
   233 	throw UninitializedParameter();
   234       }
   235     };
   236     ///\ref named-templ-param "Named parameter" for setting PredMap type
   237 
   238     ///\ref named-templ-param "Named parameter" for setting PredMap type
   239     ///
   240     template <class T>
   241     struct DefPredMap : public Dfs<Graph, DefPredMapTraits<T> > {
   242       typedef Dfs<Graph, DefPredMapTraits<T> > Create;
   243     };
   244     
   245     
   246     template <class T>
   247     struct DefDistMapTraits : public Traits {
   248       typedef T DistMap;
   249       static DistMap *createDistMap(const Graph &G) 
   250       {
   251 	throw UninitializedParameter();
   252       }
   253     };
   254     ///\ref named-templ-param "Named parameter" for setting DistMap type
   255 
   256     ///\ref named-templ-param "Named parameter" for setting DistMap type
   257     ///
   258     template <class T>
   259     struct DefDistMap {
   260       typedef Dfs<Graph, DefDistMapTraits<T> > Create;
   261     };
   262     
   263     template <class T>
   264     struct DefReachedMapTraits : public Traits {
   265       typedef T ReachedMap;
   266       static ReachedMap *createReachedMap(const Graph &G) 
   267       {
   268 	throw UninitializedParameter();
   269       }
   270     };
   271     ///\ref named-templ-param "Named parameter" for setting ReachedMap type
   272 
   273     ///\ref named-templ-param "Named parameter" for setting ReachedMap type
   274     ///
   275     template <class T>
   276     struct DefReachedMap : public Dfs< Graph, DefReachedMapTraits<T> > {
   277       typedef Dfs< Graph, DefReachedMapTraits<T> > Create;
   278     };
   279 
   280     template <class T>
   281     struct DefProcessedMapTraits : public Traits {
   282       typedef T ProcessedMap;
   283       static ProcessedMap *createProcessedMap(const Graph &G) 
   284       {
   285 	throw UninitializedParameter();
   286       }
   287     };
   288     ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
   289 
   290     ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
   291     ///
   292     template <class T>
   293     struct DefProcessedMap : public Dfs< Graph, DefProcessedMapTraits<T> > { 
   294       typedef Dfs< Graph, DefProcessedMapTraits<T> > Create;
   295     };
   296     
   297     struct DefGraphProcessedMapTraits : public Traits {
   298       typedef typename Graph::template NodeMap<bool> ProcessedMap;
   299       static ProcessedMap *createProcessedMap(const Graph &G) 
   300       {
   301 	return new ProcessedMap(G);
   302       }
   303     };
   304     ///\brief \ref named-templ-param "Named parameter"
   305     ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
   306     ///
   307     ///\ref named-templ-param "Named parameter"
   308     ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
   309     ///If you don't set it explicitely, it will be automatically allocated.
   310     template <class T>
   311     class DefProcessedMapToBeDefaultMap :
   312       public Dfs< Graph, DefGraphProcessedMapTraits> { 
   313       typedef Dfs< Graph, DefGraphProcessedMapTraits> Create;
   314     };
   315     
   316     ///@}
   317 
   318   public:      
   319     
   320     ///Constructor.
   321     
   322     ///\param _G the graph the algorithm will run on.
   323     ///
   324     Dfs(const Graph& _G) :
   325       G(&_G),
   326       _pred(NULL), local_pred(false),
   327       _dist(NULL), local_dist(false),
   328       _reached(NULL), local_reached(false),
   329       _processed(NULL), local_processed(false)
   330     { }
   331     
   332     ///Destructor.
   333     ~Dfs() 
   334     {
   335       if(local_pred) delete _pred;
   336       if(local_dist) delete _dist;
   337       if(local_reached) delete _reached;
   338       if(local_processed) delete _processed;
   339     }
   340 
   341     ///Sets the map storing the predecessor edges.
   342 
   343     ///Sets the map storing the predecessor edges.
   344     ///If you don't use this function before calling \ref run(),
   345     ///it will allocate one. The destuctor deallocates this
   346     ///automatically allocated map, of course.
   347     ///\return <tt> (*this) </tt>
   348     Dfs &predMap(PredMap &m) 
   349     {
   350       if(local_pred) {
   351 	delete _pred;
   352 	local_pred=false;
   353       }
   354       _pred = &m;
   355       return *this;
   356     }
   357 
   358     ///Sets the map storing the distances calculated by the algorithm.
   359 
   360     ///Sets the map storing the distances calculated by the algorithm.
   361     ///If you don't use this function before calling \ref run(),
   362     ///it will allocate one. The destuctor deallocates this
   363     ///automatically allocated map, of course.
   364     ///\return <tt> (*this) </tt>
   365     Dfs &distMap(DistMap &m) 
   366     {
   367       if(local_dist) {
   368 	delete _dist;
   369 	local_dist=false;
   370       }
   371       _dist = &m;
   372       return *this;
   373     }
   374 
   375     ///Sets the map indicating if a node is reached.
   376 
   377     ///Sets the map indicating if a node is reached.
   378     ///If you don't use this function before calling \ref run(),
   379     ///it will allocate one. The destuctor deallocates this
   380     ///automatically allocated map, of course.
   381     ///\return <tt> (*this) </tt>
   382     Dfs &reachedMap(ReachedMap &m) 
   383     {
   384       if(local_reached) {
   385 	delete _reached;
   386 	local_reached=false;
   387       }
   388       _reached = &m;
   389       return *this;
   390     }
   391 
   392     ///Sets the map indicating if a node is processed.
   393 
   394     ///Sets the map indicating if a node is processed.
   395     ///If you don't use this function before calling \ref run(),
   396     ///it will allocate one. The destuctor deallocates this
   397     ///automatically allocated map, of course.
   398     ///\return <tt> (*this) </tt>
   399     Dfs &processedMap(ProcessedMap &m) 
   400     {
   401       if(local_processed) {
   402 	delete _processed;
   403 	local_processed=false;
   404       }
   405       _processed = &m;
   406       return *this;
   407     }
   408 
   409   public:
   410     ///\name Execution control
   411     ///The simplest way to execute the algorithm is to use
   412     ///one of the member functions called \c run(...).
   413     ///\n
   414     ///If you need more control on the execution,
   415     ///first you must call \ref init(), then you can add a source node
   416     ///with \ref addSource().
   417     ///Finally \ref start() will perform the actual path
   418     ///computation.
   419 
   420     ///@{
   421 
   422     ///Initializes the internal data structures.
   423 
   424     ///Initializes the internal data structures.
   425     ///
   426     void init()
   427     {
   428       create_maps();
   429       _stack.resize(countNodes(*G));
   430       _stack_head=-1;
   431       for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
   432 	_pred->set(u,INVALID);
   433 	// _predNode->set(u,INVALID);
   434 	_reached->set(u,false);
   435 	_processed->set(u,false);
   436       }
   437     }
   438     
   439     ///Adds a new source node.
   440 
   441     ///Adds a new source node to the set of nodes to be processed.
   442     ///
   443     ///\bug dists are wrong (or at least strange) in case of multiple sources.
   444     void addSource(Node s)
   445     {
   446       if(!(*_reached)[s])
   447 	{
   448 	  _reached->set(s,true);
   449 	  _pred->set(s,INVALID);
   450 	  OutEdgeIt e(*G,s);
   451 	  if(e!=INVALID) {
   452 	    _stack[++_stack_head]=e;
   453 	    _dist->set(s,_stack_head);
   454 	  }
   455 	  else {
   456 	    _processed->set(s,true);
   457 	    _dist->set(s,0);
   458 	  }
   459 	}
   460     }
   461     
   462     ///Processes the next edge.
   463 
   464     ///Processes the next edge.
   465     ///
   466     ///\return The processed edge.
   467     ///
   468     ///\pre The stack must not be empty!
   469     Edge processNextEdge()
   470     { 
   471       Node m;
   472       Edge e=_stack[_stack_head];
   473       if(!(*_reached)[m=G->target(e)]) {
   474 	_pred->set(m,e);
   475 	_reached->set(m,true);
   476 	++_stack_head;
   477 	_stack[_stack_head] = OutEdgeIt(*G, m);
   478 	_dist->set(m,_stack_head);
   479       }
   480       else {
   481 	m=G->source(e);
   482 	++_stack[_stack_head];
   483       }
   484       while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
   485 	_processed->set(m,true);
   486 	--_stack_head;
   487 	if(_stack_head>=0) {
   488 	  m=G->source(_stack[_stack_head]);
   489 	  ++_stack[_stack_head];
   490 	}
   491       }
   492       return e;
   493     }
   494     ///Next edge to be processed.
   495 
   496     ///Next edge to be processed.
   497     ///
   498     ///\return The next edge to be processed or INVALID if the stack is
   499     /// empty.
   500     OutEdgeIt nextEdge()
   501     { 
   502       return _stack_head>=0?_stack[_stack_head]:INVALID;
   503     }
   504 
   505     ///\brief Returns \c false if there are nodes
   506     ///to be processed in the queue
   507     ///
   508     ///Returns \c false if there are nodes
   509     ///to be processed in the queue
   510     bool emptyQueue() { return _stack_head<0; }
   511     ///Returns the number of the nodes to be processed.
   512     
   513     ///Returns the number of the nodes to be processed in the queue.
   514     int queueSize() { return _stack_head+1; }
   515     
   516     ///Executes the algorithm.
   517 
   518     ///Executes the algorithm.
   519     ///
   520     ///\pre init() must be called and at least one node should be added
   521     ///with addSource() before using this function.
   522     ///
   523     ///This method runs the %DFS algorithm from the root node(s)
   524     ///in order to
   525     ///compute the
   526     ///%DFS path to each node. The algorithm computes
   527     ///- The %DFS tree.
   528     ///- The distance of each node from the root(s) in the %DFS tree.
   529     ///
   530     void start()
   531     {
   532       while ( !emptyQueue() ) processNextEdge();
   533     }
   534     
   535     ///Executes the algorithm until \c dest is reached.
   536 
   537     ///Executes the algorithm until \c dest is reached.
   538     ///
   539     ///\pre init() must be called and at least one node should be added
   540     ///with addSource() before using this function.
   541     ///
   542     ///This method runs the %DFS algorithm from the root node(s)
   543     ///in order to
   544     ///compute the
   545     ///%DFS path to \c dest. The algorithm computes
   546     ///- The %DFS path to \c  dest.
   547     ///- The distance of \c dest from the root(s) in the %DFS tree.
   548     ///
   549     void start(Node dest)
   550     {
   551       while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest ) 
   552 	processNextEdge();
   553     }
   554     
   555     ///Executes the algorithm until a condition is met.
   556 
   557     ///Executes the algorithm until a condition is met.
   558     ///
   559     ///\pre init() must be called and at least one node should be added
   560     ///with addSource() before using this function.
   561     ///
   562     ///\param nm must be a bool (or convertible) edge map. The algorithm
   563     ///will stop when it reaches an edge \c e with <tt>nm[e]==true</tt>.
   564     ///
   565     ///\warning Contrary to \ref Dfs and \ref Dijkstra, \c em is an edge map,
   566     ///not a node map.
   567     template<class EM>
   568     void start(const EM &em)
   569     {
   570       while ( !emptyQueue() && !em[_stack[_stack_head]] ) processNextEdge();
   571     }
   572 
   573     ///Runs %DFS algorithm from node \c s.
   574     
   575     ///This method runs the %DFS algorithm from a root node \c s
   576     ///in order to
   577     ///compute the
   578     ///%DFS path to each node. The algorithm computes
   579     ///- The %DFS tree.
   580     ///- The distance of each node from the root in the %DFS tree.
   581     ///
   582     ///\note d.run(s) is just a shortcut of the following code.
   583     ///\code
   584     ///  d.init();
   585     ///  d.addSource(s);
   586     ///  d.start();
   587     ///\endcode
   588     void run(Node s) {
   589       init();
   590       addSource(s);
   591       start();
   592     }
   593     
   594     ///Finds the %DFS path between \c s and \c t.
   595     
   596     ///Finds the %DFS path between \c s and \c t.
   597     ///
   598     ///\return The length of the %DFS s---t path if there exists one,
   599     ///0 otherwise.
   600     ///\note Apart from the return value, d.run(s,t) is
   601     ///just a shortcut of the following code.
   602     ///\code
   603     ///  d.init();
   604     ///  d.addSource(s);
   605     ///  d.start(t);
   606     ///\endcode
   607     int run(Node s,Node t) {
   608       init();
   609       addSource(s);
   610       start(t);
   611       return reached(t)?_stack_head+1:0;
   612     }
   613     
   614     ///@}
   615 
   616     ///\name Query Functions
   617     ///The result of the %DFS algorithm can be obtained using these
   618     ///functions.\n
   619     ///Before the use of these functions,
   620     ///either run() or start() must be called.
   621     
   622     ///@{
   623 
   624     ///Copies the path to \c t on the DFS tree into \c p
   625     
   626     ///This function copies the path to \c t on the DFS tree  into \c p.
   627     ///If \c t is a source itself or unreachable, then it does not
   628     ///alter \c p.
   629     ///
   630     ///\return Returns \c true if a path to \c t was actually copied to \c p,
   631     ///\c false otherwise.
   632     ///\sa DirPath
   633     template<class P>
   634     bool getPath(P &p,Node t) 
   635     {
   636       if(reached(t)) {
   637 	p.clear();
   638 	typename P::Builder b(p);
   639 	for(b.setStartNode(t);predEdge(t)!=INVALID;t=predNode(t))
   640 	  b.pushFront(predEdge(t));
   641 	b.commit();
   642 	return true;
   643       }
   644       return false;
   645     }
   646 
   647     ///The distance of a node from the root(s).
   648 
   649     ///Returns the distance of a node from the root(s).
   650     ///\pre \ref run() must be called before using this function.
   651     ///\warning If node \c v is unreachable from the root(s) then the return value
   652     ///of this funcion is undefined.
   653     int dist(Node v) const { return (*_dist)[v]; }
   654 
   655     ///Returns the 'previous edge' of the %DFS tree.
   656 
   657     ///For a node \c v it returns the 'previous edge'
   658     ///of the %DFS path,
   659     ///i.e. it returns the last edge of a %DFS path from the root(s) to \c
   660     ///v. It is \ref INVALID
   661     ///if \c v is unreachable from the root(s) or \c v is a root. The
   662     ///%DFS tree used here is equal to the %DFS tree used in
   663     ///\ref predNode().
   664     ///\pre Either \ref run() or \ref start() must be called before using
   665     ///this function.
   666     Edge predEdge(Node v) const { return (*_pred)[v];}
   667 
   668     ///Returns the 'previous node' of the %DFS tree.
   669 
   670     ///For a node \c v it returns the 'previous node'
   671     ///of the %DFS tree,
   672     ///i.e. it returns the last but one node from a %DFS path from the
   673     ///root(a) to \c /v.
   674     ///It is INVALID if \c v is unreachable from the root(s) or
   675     ///if \c v itself a root.
   676     ///The %DFS tree used here is equal to the %DFS
   677     ///tree used in \ref predEdge().
   678     ///\pre Either \ref run() or \ref start() must be called before
   679     ///using this function.
   680     Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
   681 				  G->source((*_pred)[v]); }
   682     
   683     ///Returns a reference to the NodeMap of distances.
   684 
   685     ///Returns a reference to the NodeMap of distances.
   686     ///\pre Either \ref run() or \ref init() must
   687     ///be called before using this function.
   688     const DistMap &distMap() const { return *_dist;}
   689  
   690     ///Returns a reference to the %DFS edge-tree map.
   691 
   692     ///Returns a reference to the NodeMap of the edges of the
   693     ///%DFS tree.
   694     ///\pre Either \ref run() or \ref init()
   695     ///must be called before using this function.
   696     const PredMap &predMap() const { return *_pred;}
   697  
   698     ///Checks if a node is reachable from the root.
   699 
   700     ///Returns \c true if \c v is reachable from the root(s).
   701     ///\warning The source nodes are inditated as unreachable.
   702     ///\pre Either \ref run() or \ref start()
   703     ///must be called before using this function.
   704     ///
   705     bool reached(Node v) { return (*_reached)[v]; }
   706     
   707     ///@}
   708   };
   709 
   710   ///Default traits class of Dfs function.
   711 
   712   ///Default traits class of Dfs function.
   713   ///\param GR Graph type.
   714   template<class GR>
   715   struct DfsWizardDefaultTraits
   716   {
   717     ///The graph type the algorithm runs on. 
   718     typedef GR Graph;
   719     ///\brief The type of the map that stores the last
   720     ///edges of the %DFS paths.
   721     /// 
   722     ///The type of the map that stores the last
   723     ///edges of the %DFS paths.
   724     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   725     ///
   726     typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
   727     ///Instantiates a PredMap.
   728  
   729     ///This function instantiates a \ref PredMap. 
   730     ///\param g is the graph, to which we would like to define the PredMap.
   731     ///\todo The graph alone may be insufficient to initialize
   732 #ifdef DOXYGEN
   733     static PredMap *createPredMap(const GR &g) 
   734 #else
   735     static PredMap *createPredMap(const GR &) 
   736 #endif
   737     {
   738       return new PredMap();
   739     }
   740 
   741     ///The type of the map that indicates which nodes are processed.
   742  
   743     ///The type of the map that indicates which nodes are processed.
   744     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   745     ///\todo named parameter to set this type, function to read and write.
   746     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
   747     ///Instantiates a ProcessedMap.
   748  
   749     ///This function instantiates a \ref ProcessedMap. 
   750     ///\param g is the graph, to which
   751     ///we would like to define the \ref ProcessedMap
   752 #ifdef DOXYGEN
   753     static ProcessedMap *createProcessedMap(const GR &g)
   754 #else
   755     static ProcessedMap *createProcessedMap(const GR &)
   756 #endif
   757     {
   758       return new ProcessedMap();
   759     }
   760     ///The type of the map that indicates which nodes are reached.
   761  
   762     ///The type of the map that indicates which nodes are reached.
   763     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   764     ///\todo named parameter to set this type, function to read and write.
   765     typedef typename Graph::template NodeMap<bool> ReachedMap;
   766     ///Instantiates a ReachedMap.
   767  
   768     ///This function instantiates a \ref ReachedMap. 
   769     ///\param G is the graph, to which
   770     ///we would like to define the \ref ReachedMap.
   771     static ReachedMap *createReachedMap(const GR &G)
   772     {
   773       return new ReachedMap(G);
   774     }
   775     ///The type of the map that stores the dists of the nodes.
   776  
   777     ///The type of the map that stores the dists of the nodes.
   778     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   779     ///
   780     typedef NullMap<typename Graph::Node,int> DistMap;
   781     ///Instantiates a DistMap.
   782  
   783     ///This function instantiates a \ref DistMap. 
   784     ///\param g is the graph, to which we would like to define the \ref DistMap
   785 #ifdef DOXYGEN
   786     static DistMap *createDistMap(const GR &g)
   787 #else
   788     static DistMap *createDistMap(const GR &)
   789 #endif
   790     {
   791       return new DistMap();
   792     }
   793   };
   794   
   795   /// Default traits used by \ref DfsWizard
   796 
   797   /// To make it easier to use Dfs algorithm
   798   ///we have created a wizard class.
   799   /// This \ref DfsWizard class needs default traits,
   800   ///as well as the \ref Dfs class.
   801   /// The \ref DfsWizardBase is a class to be the default traits of the
   802   /// \ref DfsWizard class.
   803   template<class GR>
   804   class DfsWizardBase : public DfsWizardDefaultTraits<GR>
   805   {
   806 
   807     typedef DfsWizardDefaultTraits<GR> Base;
   808   protected:
   809     /// Type of the nodes in the graph.
   810     typedef typename Base::Graph::Node Node;
   811 
   812     /// Pointer to the underlying graph.
   813     void *_g;
   814     ///Pointer to the map of reached nodes.
   815     void *_reached;
   816     ///Pointer to the map of processed nodes.
   817     void *_processed;
   818     ///Pointer to the map of predecessors edges.
   819     void *_pred;
   820     ///Pointer to the map of distances.
   821     void *_dist;
   822     ///Pointer to the source node.
   823     Node _source;
   824     
   825     public:
   826     /// Constructor.
   827     
   828     /// This constructor does not require parameters, therefore it initiates
   829     /// all of the attributes to default values (0, INVALID).
   830     DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
   831 			   _dist(0), _source(INVALID) {}
   832 
   833     /// Constructor.
   834     
   835     /// This constructor requires some parameters,
   836     /// listed in the parameters list.
   837     /// Others are initiated to 0.
   838     /// \param g is the initial value of  \ref _g
   839     /// \param s is the initial value of  \ref _source
   840     DfsWizardBase(const GR &g, Node s=INVALID) :
   841       _g((void *)&g), _reached(0), _processed(0), _pred(0),
   842       _dist(0), _source(s) {}
   843 
   844   };
   845   
   846   /// A class to make the usage of the Dfs algorithm easier
   847 
   848   /// This class is created to make it easier to use the Dfs algorithm.
   849   /// It uses the functions and features of the plain \ref Dfs,
   850   /// but it is much simpler to use it.
   851   ///
   852   /// Simplicity means that the way to change the types defined
   853   /// in the traits class is based on functions that returns the new class
   854   /// and not on templatable built-in classes.
   855   /// When using the plain \ref Dfs
   856   /// the new class with the modified type comes from
   857   /// the original class by using the ::
   858   /// operator. In the case of \ref DfsWizard only
   859   /// a function have to be called and it will
   860   /// return the needed class.
   861   ///
   862   /// It does not have own \ref run method. When its \ref run method is called
   863   /// it initiates a plain \ref Dfs object, and calls the \ref Dfs::run
   864   /// method of it.
   865   template<class TR>
   866   class DfsWizard : public TR
   867   {
   868     typedef TR Base;
   869 
   870     ///The type of the underlying graph.
   871     typedef typename TR::Graph Graph;
   872     //\e
   873     typedef typename Graph::Node Node;
   874     //\e
   875     typedef typename Graph::NodeIt NodeIt;
   876     //\e
   877     typedef typename Graph::Edge Edge;
   878     //\e
   879     typedef typename Graph::OutEdgeIt OutEdgeIt;
   880     
   881     ///\brief The type of the map that stores
   882     ///the reached nodes
   883     typedef typename TR::ReachedMap ReachedMap;
   884     ///\brief The type of the map that stores
   885     ///the processed nodes
   886     typedef typename TR::ProcessedMap ProcessedMap;
   887     ///\brief The type of the map that stores the last
   888     ///edges of the %DFS paths.
   889     typedef typename TR::PredMap PredMap;
   890     ///The type of the map that stores the distances of the nodes.
   891     typedef typename TR::DistMap DistMap;
   892 
   893 public:
   894     /// Constructor.
   895     DfsWizard() : TR() {}
   896 
   897     /// Constructor that requires parameters.
   898 
   899     /// Constructor that requires parameters.
   900     /// These parameters will be the default values for the traits class.
   901     DfsWizard(const Graph &g, Node s=INVALID) :
   902       TR(g,s) {}
   903 
   904     ///Copy constructor
   905     DfsWizard(const TR &b) : TR(b) {}
   906 
   907     ~DfsWizard() {}
   908 
   909     ///Runs Dfs algorithm from a given node.
   910     
   911     ///Runs Dfs algorithm from a given node.
   912     ///The node can be given by the \ref source function.
   913     void run()
   914     {
   915       if(Base::_source==INVALID) throw UninitializedParameter();
   916       Dfs<Graph,TR> alg(*(Graph*)Base::_g);
   917       if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
   918       if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
   919       if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
   920       if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
   921       alg.run(Base::_source);
   922     }
   923 
   924     ///Runs Dfs algorithm from the given node.
   925 
   926     ///Runs Dfs algorithm from the given node.
   927     ///\param s is the given source.
   928     void run(Node s)
   929     {
   930       Base::_source=s;
   931       run();
   932     }
   933 
   934     template<class T>
   935     struct DefPredMapBase : public Base {
   936       typedef T PredMap;
   937       static PredMap *createPredMap(const Graph &) { return 0; };
   938       DefPredMapBase(const TR &b) : TR(b) {}
   939     };
   940     
   941     ///\brief \ref named-templ-param "Named parameter"
   942     ///function for setting PredMap type
   943     ///
   944     /// \ref named-templ-param "Named parameter"
   945     ///function for setting PredMap type
   946     ///
   947     template<class T>
   948     DfsWizard<DefPredMapBase<T> > predMap(const T &t) 
   949     {
   950       Base::_pred=(void *)&t;
   951       return DfsWizard<DefPredMapBase<T> >(*this);
   952     }
   953     
   954  
   955     template<class T>
   956     struct DefReachedMapBase : public Base {
   957       typedef T ReachedMap;
   958       static ReachedMap *createReachedMap(const Graph &) { return 0; };
   959       DefReachedMapBase(const TR &b) : TR(b) {}
   960     };
   961     
   962     ///\brief \ref named-templ-param "Named parameter"
   963     ///function for setting ReachedMap
   964     ///
   965     /// \ref named-templ-param "Named parameter"
   966     ///function for setting ReachedMap
   967     ///
   968     template<class T>
   969     DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) 
   970     {
   971       Base::_pred=(void *)&t;
   972       return DfsWizard<DefReachedMapBase<T> >(*this);
   973     }
   974     
   975 
   976     template<class T>
   977     struct DefProcessedMapBase : public Base {
   978       typedef T ProcessedMap;
   979       static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
   980       DefProcessedMapBase(const TR &b) : TR(b) {}
   981     };
   982     
   983     ///\brief \ref named-templ-param "Named parameter"
   984     ///function for setting ProcessedMap
   985     ///
   986     /// \ref named-templ-param "Named parameter"
   987     ///function for setting ProcessedMap
   988     ///
   989     template<class T>
   990     DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) 
   991     {
   992       Base::_pred=(void *)&t;
   993       return DfsWizard<DefProcessedMapBase<T> >(*this);
   994     }
   995     
   996     template<class T>
   997     struct DefDistMapBase : public Base {
   998       typedef T DistMap;
   999       static DistMap *createDistMap(const Graph &) { return 0; };
  1000       DefDistMapBase(const TR &b) : TR(b) {}
  1001     };
  1002     
  1003     ///\brief \ref named-templ-param "Named parameter"
  1004     ///function for setting DistMap type
  1005     ///
  1006     /// \ref named-templ-param "Named parameter"
  1007     ///function for setting DistMap type
  1008     ///
  1009     template<class T>
  1010     DfsWizard<DefDistMapBase<T> > distMap(const T &t) 
  1011     {
  1012       Base::_dist=(void *)&t;
  1013       return DfsWizard<DefDistMapBase<T> >(*this);
  1014     }
  1015     
  1016     /// Sets the source node, from which the Dfs algorithm runs.
  1017 
  1018     /// Sets the source node, from which the Dfs algorithm runs.
  1019     /// \param s is the source node.
  1020     DfsWizard<TR> &source(Node s) 
  1021     {
  1022       Base::_source=s;
  1023       return *this;
  1024     }
  1025     
  1026   };
  1027   
  1028   ///Function type interface for Dfs algorithm.
  1029 
  1030   /// \ingroup flowalgs
  1031   ///Function type interface for Dfs algorithm.
  1032   ///
  1033   ///This function also has several
  1034   ///\ref named-templ-func-param "named parameters",
  1035   ///they are declared as the members of class \ref DfsWizard.
  1036   ///The following
  1037   ///example shows how to use these parameters.
  1038   ///\code
  1039   ///  dfs(g,source).predMap(preds).run();
  1040   ///\endcode
  1041   ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
  1042   ///to the end of the parameter list.
  1043   ///\sa DfsWizard
  1044   ///\sa Dfs
  1045   template<class GR>
  1046   DfsWizard<DfsWizardBase<GR> >
  1047   dfs(const GR &g,typename GR::Node s=INVALID)
  1048   {
  1049     return DfsWizard<DfsWizardBase<GR> >(g,s);
  1050   }
  1051 
  1052 #ifdef DOXYGEN
  1053   /// \brief Visitor class for dfs.
  1054   ///  
  1055   /// It gives a simple interface for a functional interface for dfs 
  1056   /// traversal. The traversal on a linear data structure. 
  1057   template <typename _Graph>
  1058   struct DfsVisitor {
  1059     typedef _Graph Graph;
  1060     typedef typename Graph::Edge Edge;
  1061     typedef typename Graph::Node Node;
  1062     /// \brief Called when the edge reach a node.
  1063     /// 
  1064     /// It is called when the dfs find an edge which target is not
  1065     /// reached yet.
  1066     void discover(const Edge& edge) {}
  1067     /// \brief Called when the node reached first time.
  1068     /// 
  1069     /// It is Called when the node reached first time.
  1070     void reach(const Node& node) {}
  1071     /// \brief Called when we step back on an edge.
  1072     /// 
  1073     /// It is called when the dfs should step back on the edge.
  1074     void backtrack(const Edge& edge) {}
  1075     /// \brief Called when we step back from the node.
  1076     /// 
  1077     /// It is called when we step back from the node.
  1078     void leave(const Node& node) {}
  1079     /// \brief Called when the edge examined but target of the edge 
  1080     /// already discovered.
  1081     /// 
  1082     /// It called when the edge examined but the target of the edge 
  1083     /// already discovered.
  1084     void examine(const Edge& edge) {}
  1085     /// \brief Called for the source node of the dfs.
  1086     /// 
  1087     /// It is called for the source node of the dfs.
  1088     void start(const Node& node) {}
  1089     /// \brief Called when we leave the source node of the dfs.
  1090     /// 
  1091     /// It is called when we leave the source node of the dfs.
  1092     void stop(const Node& node) {}
  1093 
  1094   };
  1095 #else
  1096   template <typename _Graph>
  1097   struct DfsVisitor {
  1098     typedef _Graph Graph;
  1099     typedef typename Graph::Edge Edge;
  1100     typedef typename Graph::Node Node;
  1101     void discover(const Edge&) {}
  1102     void reach(const Node&) {}
  1103     void backtrack(const Edge&) {}
  1104     void leave(const Node&) {}
  1105     void examine(const Edge&) {}
  1106     void start(const Node&) {}
  1107     void stop(const Node&) {}
  1108 
  1109     template <typename _Visitor>
  1110     struct Constraints {
  1111       void constraints() {
  1112 	Edge edge;
  1113 	Node node;
  1114 	visitor.discover(edge);
  1115 	visitor.reach(node);
  1116 	visitor.backtrack(edge);
  1117 	visitor.leave(node);
  1118 	visitor.examine(edge);
  1119 	visitor.start(node);
  1120 	visitor.stop(edge);
  1121       }
  1122       _Visitor& visitor;
  1123     };
  1124   };
  1125 #endif
  1126 
  1127   /// \brief Default traits class of DfsVisit class.
  1128   ///
  1129   /// Default traits class of DfsVisit class.
  1130   /// \param _Graph Graph type.
  1131   template<class _Graph>
  1132   struct DfsVisitDefaultTraits {
  1133 
  1134     /// \brief The graph type the algorithm runs on. 
  1135     typedef _Graph Graph;
  1136 
  1137     /// \brief The type of the map that indicates which nodes are reached.
  1138     /// 
  1139     /// The type of the map that indicates which nodes are reached.
  1140     /// It must meet the \ref concept::WriteMap "WriteMap" concept.
  1141     /// \todo named parameter to set this type, function to read and write.
  1142     typedef typename Graph::template NodeMap<bool> ReachedMap;
  1143 
  1144     /// \brief Instantiates a ReachedMap.
  1145     ///
  1146     /// This function instantiates a \ref ReachedMap. 
  1147     /// \param G is the graph, to which
  1148     /// we would like to define the \ref ReachedMap.
  1149     static ReachedMap *createReachedMap(const Graph &graph) {
  1150       return new ReachedMap(graph);
  1151     }
  1152 
  1153   };
  1154   
  1155   /// %DFS Visit algorithm class.
  1156   
  1157   /// \ingroup flowalgs
  1158   /// This class provides an efficient implementation of the %DFS algorithm
  1159   /// with visitor interface.
  1160   ///
  1161   /// The %DfsVisit class provides an alternative interface to the Dfs
  1162   /// class. It works with callback mechanism, the DfsVisit object calls
  1163   /// on every dfs event the \c Visitor class member functions. 
  1164   ///
  1165   /// \param _Graph The graph type the algorithm runs on. The default value is
  1166   /// \ref ListGraph. The value of _Graph is not used directly by Dfs, it
  1167   /// is only passed to \ref DfsDefaultTraits.
  1168   /// \param _Visitor The Visitor object for the algorithm. The 
  1169   /// \ref DfsVisitor "DfsVisitor<_Graph>" is an empty Visitor which
  1170   /// does not observe the Dfs events. If you want to observe the dfs
  1171   /// events you should implement your own Visitor class.
  1172   /// \param _Traits Traits class to set various data types used by the 
  1173   /// algorithm. The default traits class is
  1174   /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Graph>".
  1175   /// See \ref DfsVisitDefaultTraits for the documentation of
  1176   /// a Dfs visit traits class.
  1177   ///
  1178   /// \author Jacint Szabo, Alpar Juttner and Balazs Dezso
  1179 #ifdef DOXYGEN
  1180   template <typename _Graph, typename _Visitor, typename _Traits>
  1181 #else
  1182   template <typename _Graph = ListGraph,
  1183 	    typename _Visitor = DfsVisitor<_Graph>,
  1184 	    typename _Traits = DfsDefaultTraits<_Graph> >
  1185 #endif
  1186   class DfsVisit {
  1187   public:
  1188     
  1189     /// \brief \ref Exception for uninitialized parameters.
  1190     ///
  1191     /// This error represents problems in the initialization
  1192     /// of the parameters of the algorithms.
  1193     class UninitializedParameter : public lemon::UninitializedParameter {
  1194     public:
  1195       virtual const char* exceptionName() const {
  1196 	return "lemon::DfsVisit::UninitializedParameter";
  1197       }
  1198     };
  1199 
  1200     typedef _Traits Traits;
  1201 
  1202     typedef typename Traits::Graph Graph;
  1203 
  1204     typedef _Visitor Visitor;
  1205 
  1206     ///The type of the map indicating which nodes are reached.
  1207     typedef typename Traits::ReachedMap ReachedMap;
  1208 
  1209   private:
  1210 
  1211     typedef typename Graph::Node Node;
  1212     typedef typename Graph::NodeIt NodeIt;
  1213     typedef typename Graph::Edge Edge;
  1214     typedef typename Graph::OutEdgeIt OutEdgeIt;
  1215 
  1216     /// Pointer to the underlying graph.
  1217     const Graph *_graph;
  1218     /// Pointer to the visitor object.
  1219     Visitor *_visitor;
  1220     ///Pointer to the map of reached status of the nodes.
  1221     ReachedMap *_reached;
  1222     ///Indicates if \ref _reached is locally allocated (\c true) or not.
  1223     bool local_reached;
  1224 
  1225     std::vector<typename Graph::Edge> _stack;
  1226     int _stack_head;
  1227 
  1228     /// \brief Creates the maps if necessary.
  1229     ///
  1230     /// Creates the maps if necessary.
  1231     void create_maps() {
  1232       if(!_reached) {
  1233 	local_reached = true;
  1234 	_reached = Traits::createReachedMap(*_graph);
  1235       }
  1236     }
  1237 
  1238   protected:
  1239 
  1240     DfsVisit() {}
  1241     
  1242   public:
  1243 
  1244     typedef DfsVisit Create;
  1245 
  1246     /// \name Named template parameters
  1247 
  1248     ///@{
  1249     template <class T>
  1250     struct DefReachedMapTraits : public Traits {
  1251       typedef T ReachedMap;
  1252       static ReachedMap *createReachedMap(const Graph &graph) {
  1253 	throw UninitializedParameter();
  1254       }
  1255     };
  1256     /// \brief \ref named-templ-param "Named parameter" for setting 
  1257     /// ReachedMap type
  1258     ///
  1259     /// \ref named-templ-param "Named parameter" for setting ReachedMap type
  1260     template <class T>
  1261     struct DefReachedMap : public DfsVisit< Graph, Visitor,
  1262 					    DefReachedMapTraits<T> > {
  1263       typedef DfsVisit< Graph, Visitor, DefReachedMapTraits<T> > Create;
  1264     };
  1265     ///@}
  1266 
  1267   public:      
  1268     
  1269     /// \brief Constructor.
  1270     ///
  1271     /// Constructor.
  1272     ///
  1273     /// \param graph the graph the algorithm will run on.
  1274     /// \param visitor The visitor of the algorithm.
  1275     ///
  1276     DfsVisit(const Graph& graph, Visitor& visitor) 
  1277       : _graph(&graph), _visitor(&visitor),
  1278 	_reached(0), local_reached(false) {}
  1279     
  1280     /// \brief Destructor.
  1281     ///
  1282     /// Destructor.
  1283     ~DfsVisit() {
  1284       if(local_reached) delete _reached;
  1285     }
  1286 
  1287     /// \brief Sets the map indicating if a node is reached.
  1288     ///
  1289     /// Sets the map indicating if a node is reached.
  1290     /// If you don't use this function before calling \ref run(),
  1291     /// it will allocate one. The destuctor deallocates this
  1292     /// automatically allocated map, of course.
  1293     /// \return <tt> (*this) </tt>
  1294     DfsVisit &reachedMap(ReachedMap &m) {
  1295       if(local_reached) {
  1296 	delete _reached;
  1297 	local_reached=false;
  1298       }
  1299       _reached = &m;
  1300       return *this;
  1301     }
  1302 
  1303   public:
  1304     /// \name Execution control
  1305     /// The simplest way to execute the algorithm is to use
  1306     /// one of the member functions called \c run(...).
  1307     /// \n
  1308     /// If you need more control on the execution,
  1309     /// first you must call \ref init(), then you can adda source node
  1310     /// with \ref addSource().
  1311     /// Finally \ref start() will perform the actual path
  1312     /// computation.
  1313 
  1314     /// @{
  1315     /// \brief Initializes the internal data structures.
  1316     ///
  1317     /// Initializes the internal data structures.
  1318     ///
  1319     void init() {
  1320       create_maps();
  1321       _stack.resize(countNodes(*_graph));
  1322       _stack_head = -1;
  1323       for (NodeIt u(*_graph) ; u != INVALID ; ++u) {
  1324 	_reached->set(u, false);
  1325       }
  1326     }
  1327     
  1328     /// \brief Adds a new source node.
  1329     ///
  1330     /// Adds a new source node to the set of nodes to be processed.
  1331     void addSource(Node s) {
  1332       if(!(*_reached)[s]) {
  1333 	  _reached->set(s,true);
  1334 	  _visitor->start(s);
  1335 	  _visitor->reach(s);
  1336 	  Edge e; 
  1337 	  _graph->firstOut(e, s);
  1338 	  if (e != INVALID) {
  1339 	    _stack[++_stack_head] = e;
  1340 	  } else {
  1341 	    _visitor->leave(s);
  1342 	  }
  1343 	}
  1344     }
  1345     
  1346     /// \brief Processes the next edge.
  1347     ///
  1348     /// Processes the next edge.
  1349     ///
  1350     /// \return The processed edge.
  1351     ///
  1352     /// \pre The stack must not be empty!
  1353     Edge processNextEdge() { 
  1354       Edge e = _stack[_stack_head];
  1355       Node m = _graph->target(e);
  1356       if(!(*_reached)[m]) {
  1357 	_visitor->discover(e);
  1358 	_visitor->reach(m);
  1359 	_reached->set(m, true);
  1360 	_graph->firstOut(_stack[++_stack_head], m);
  1361       } else {
  1362 	_visitor->examine(e);
  1363 	m = _graph->source(e);
  1364 	_graph->nextOut(_stack[_stack_head]);
  1365       }
  1366       while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
  1367 	_visitor->leave(m);
  1368 	--_stack_head;
  1369 	if (_stack_head >= 0) {
  1370 	  _visitor->backtrack(_stack[_stack_head]);
  1371 	  m = _graph->source(_stack[_stack_head]);
  1372 	  _graph->nextOut(_stack[_stack_head]);
  1373 	} else {
  1374 	  _visitor->stop(m);	  
  1375 	}
  1376       }
  1377       return e;
  1378     }
  1379 
  1380     /// \brief Next edge to be processed.
  1381     ///
  1382     /// Next edge to be processed.
  1383     ///
  1384     /// \return The next edge to be processed or INVALID if the stack is
  1385     /// empty.
  1386     Edge nextEdge() { 
  1387       return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
  1388     }
  1389 
  1390     /// \brief Returns \c false if there are nodes
  1391     /// to be processed in the queue
  1392     ///
  1393     /// Returns \c false if there are nodes
  1394     /// to be processed in the queue
  1395     bool emptyQueue() { return _stack_head < 0; }
  1396 
  1397     /// \brief Returns the number of the nodes to be processed.
  1398     ///
  1399     /// Returns the number of the nodes to be processed in the queue.
  1400     int queueSize() { return _stack_head + 1; }
  1401     
  1402     /// \brief Executes the algorithm.
  1403     ///
  1404     /// Executes the algorithm.
  1405     ///
  1406     /// \pre init() must be called and at least one node should be added
  1407     /// with addSource() before using this function.
  1408     void start() {
  1409       while ( !emptyQueue() ) processNextEdge();
  1410     }
  1411     
  1412     /// \brief Executes the algorithm until \c dest is reached.
  1413     ///
  1414     /// Executes the algorithm until \c dest is reached.
  1415     ///
  1416     /// \pre init() must be called and at least one node should be added
  1417     /// with addSource() before using this function.
  1418     void start(Node dest) {
  1419       while ( !emptyQueue() && _graph->target(_stack[_stack_head]) != dest) 
  1420 	processNextEdge();
  1421     }
  1422     
  1423     /// \brief Executes the algorithm until a condition is met.
  1424     ///
  1425     /// Executes the algorithm until a condition is met.
  1426     ///
  1427     /// \pre init() must be called and at least one node should be added
  1428     /// with addSource() before using this function.
  1429     ///
  1430     /// \param nm must be a bool (or convertible) edge map. The algorithm
  1431     /// will stop when it reaches an edge \c e with <tt>nm[e]==true</tt>.
  1432     ///
  1433     /// \warning Contrary to \ref Dfs and \ref Dijkstra, \c em is an edge map,
  1434     /// not a node map.
  1435     template <typename EM>
  1436     void start(const EM &em) {
  1437       while (!emptyQueue() && !em[_stack[_stack_head]]) processNextEdge();
  1438     }
  1439 
  1440     /// \brief Runs %DFS algorithm from node \c s.
  1441     ///
  1442     /// This method runs the %DFS algorithm from a root node \c s.
  1443     /// \note d.run(s) is just a shortcut of the following code.
  1444     /// \code
  1445     ///   d.init();
  1446     ///   d.addSource(s);
  1447     ///   d.start();
  1448     /// \endcode
  1449     void run(Node s) {
  1450       init();
  1451       addSource(s);
  1452       start();
  1453     }
  1454     ///@}
  1455 
  1456     /// \name Query Functions
  1457     /// The result of the %DFS algorithm can be obtained using these
  1458     /// functions.\n
  1459     /// Before the use of these functions,
  1460     /// either run() or start() must be called.
  1461     ///@{
  1462     /// \brief Checks if a node is reachable from the root.
  1463     ///
  1464     /// Returns \c true if \c v is reachable from the root(s).
  1465     /// \warning The source nodes are inditated as unreachable.
  1466     /// \pre Either \ref run() or \ref start()
  1467     /// must be called before using this function.
  1468     ///
  1469     bool reached(Node v) { return (*_reached)[v]; }
  1470     ///@}
  1471   };
  1472 
  1473 
  1474 } //END OF NAMESPACE LEMON
  1475 
  1476 #endif
  1477