alpar@906: /* -*- C++ -*-
alpar@921:  * src/lemon/dfs.h - Part of LEMON, a generic C++ optimization library
alpar@906:  *
alpar@1164:  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906:  *
alpar@906:  * Permission to use, modify and distribute this software is granted
alpar@906:  * provided that this copyright notice appears in all copies. For
alpar@906:  * precise terms see the accompanying LICENSE file.
alpar@906:  *
alpar@906:  * This software is provided "AS IS" with no warranty of any kind,
alpar@906:  * express or implied, and with no claim as to its suitability for any
alpar@906:  * purpose.
alpar@906:  *
alpar@906:  */
alpar@906: 
alpar@921: #ifndef LEMON_DFS_H
alpar@921: #define LEMON_DFS_H
alpar@780: 
alpar@780: ///\ingroup flowalgs
alpar@780: ///\file
alpar@1218: ///\brief Dfs algorithm.
alpar@780: 
alpar@1218: #include <lemon/list_graph.h>
klao@946: #include <lemon/graph_utils.h>
alpar@921: #include <lemon/invalid.h>
alpar@1218: #include <lemon/error.h>
alpar@1218: #include <lemon/maps.h>
alpar@780: 
alpar@921: namespace lemon {
alpar@780: 
alpar@780: 
alpar@1218:   
alpar@1218:   ///Default traits class of Dfs class.
alpar@1218: 
alpar@1218:   ///Default traits class of Dfs class.
alpar@1218:   ///\param GR Graph type.
alpar@1218:   template<class GR>
alpar@1218:   struct DfsDefaultTraits
alpar@1218:   {
alpar@1218:     ///The graph type the algorithm runs on. 
alpar@1218:     typedef GR Graph;
alpar@1218:     ///\brief The type of the map that stores the last
alpar@1218:     ///edges of the %DFS paths.
alpar@1218:     /// 
alpar@1218:     ///The type of the map that stores the last
alpar@1218:     ///edges of the %DFS paths.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///
alpar@1218:     typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
alpar@1218:     ///Instantiates a PredMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref PredMap. 
alpar@1218:     ///\param G is the graph, to which we would like to define the PredMap.
alpar@1218:     ///\todo The graph alone may be insufficient to initialize
alpar@1218:     static PredMap *createPredMap(const GR &G) 
alpar@1218:     {
alpar@1218:       return new PredMap(G);
alpar@1218:     }
alpar@1218: //     ///\brief The type of the map that stores the last but one
alpar@1218: //     ///nodes of the %DFS paths.
alpar@1218: //     ///
alpar@1218: //     ///The type of the map that stores the last but one
alpar@1218: //     ///nodes of the %DFS paths.
alpar@1218: //     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218: //     ///
alpar@1218: //     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
alpar@1218: //     ///Instantiates a PredNodeMap.
alpar@1218:     
alpar@1218: //     ///This function instantiates a \ref PredNodeMap. 
alpar@1218: //     ///\param G is the graph, to which
alpar@1218: //     ///we would like to define the \ref PredNodeMap
alpar@1218: //     static PredNodeMap *createPredNodeMap(const GR &G)
alpar@1218: //     {
alpar@1218: //       return new PredNodeMap();
alpar@1218: //     }
alpar@1218: 
alpar@1218:     ///The type of the map that indicates which nodes are processed.
alpar@1218:  
alpar@1218:     ///The type of the map that indicates which nodes are processed.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///\todo named parameter to set this type, function to read and write.
alpar@1218:     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
alpar@1218:     ///Instantiates a ProcessedMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref ProcessedMap. 
alpar@1218:     ///\param G is the graph, to which
alpar@1218:     ///we would like to define the \ref ProcessedMap
alpar@1367:     static ProcessedMap *createProcessedMap(const GR &)
alpar@1218:     {
alpar@1218:       return new ProcessedMap();
alpar@1218:     }
alpar@1218:     ///The type of the map that indicates which nodes are reached.
alpar@1218:  
alpar@1218:     ///The type of the map that indicates which nodes are reached.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///\todo named parameter to set this type, function to read and write.
alpar@1218:     typedef typename Graph::template NodeMap<bool> ReachedMap;
alpar@1218:     ///Instantiates a ReachedMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref ReachedMap. 
alpar@1218:     ///\param G is the graph, to which
alpar@1218:     ///we would like to define the \ref ReachedMap.
alpar@1218:     static ReachedMap *createReachedMap(const GR &G)
alpar@1218:     {
alpar@1218:       return new ReachedMap(G);
alpar@1218:     }
alpar@1218:     ///The type of the map that stores the dists of the nodes.
alpar@1218:  
alpar@1218:     ///The type of the map that stores the dists of the nodes.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///
alpar@1218:     typedef typename Graph::template NodeMap<int> DistMap;
alpar@1218:     ///Instantiates a DistMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref DistMap. 
alpar@1218:     ///\param G is the graph, to which we would like to define the \ref DistMap
alpar@1218:     static DistMap *createDistMap(const GR &G)
alpar@1218:     {
alpar@1218:       return new DistMap(G);
alpar@1218:     }
alpar@1218:   };
alpar@1218:   
alpar@781:   ///%DFS algorithm class.
alpar@1218:   
alpar@1218:   ///\ingroup flowalgs
alpar@1218:   ///This class provides an efficient implementation of the %DFS algorithm.
alpar@780:   ///
alpar@1218:   ///\param GR The graph type the algorithm runs on. The default value is
alpar@1218:   ///\ref ListGraph. The value of GR is not used directly by Dfs, it
alpar@1218:   ///is only passed to \ref DfsDefaultTraits.
alpar@1218:   ///\param TR Traits class to set various data types used by the algorithm.
alpar@1218:   ///The default traits class is
alpar@1218:   ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
alpar@1218:   ///See \ref DfsDefaultTraits for the documentation of
alpar@1218:   ///a Dfs traits class.
alpar@780:   ///
alpar@1218:   ///\author Jacint Szabo and Alpar Juttner
alpar@1218:   ///\todo A compare object would be nice.
alpar@780: 
alpar@780: #ifdef DOXYGEN
alpar@1218:   template <typename GR,
alpar@1218: 	    typename TR>
alpar@780: #else
alpar@1218:   template <typename GR=ListGraph,
alpar@1218: 	    typename TR=DfsDefaultTraits<GR> >
alpar@780: #endif
alpar@1218:   class Dfs {
alpar@780:   public:
alpar@1218:     /**
alpar@1218:      * \brief \ref Exception for uninitialized parameters.
alpar@1218:      *
alpar@1218:      * This error represents problems in the initialization
alpar@1218:      * of the parameters of the algorithms.
alpar@1218:      */
alpar@1218:     class UninitializedParameter : public lemon::UninitializedParameter {
alpar@1218:     public:
alpar@1218:       virtual const char* exceptionName() const {
alpar@1218: 	return "lemon::Dfs::UninitializedParameter";
alpar@1218:       }
alpar@1218:     };
alpar@1218: 
alpar@1218:     typedef TR Traits;
alpar@780:     ///The type of the underlying graph.
alpar@1218:     typedef typename TR::Graph Graph;
alpar@911:     ///\e
alpar@780:     typedef typename Graph::Node Node;
alpar@911:     ///\e
alpar@780:     typedef typename Graph::NodeIt NodeIt;
alpar@911:     ///\e
alpar@780:     typedef typename Graph::Edge Edge;
alpar@911:     ///\e
alpar@780:     typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@780:     
alpar@780:     ///\brief The type of the map that stores the last
alpar@1218:     ///edges of the %DFS paths.
alpar@1218:     typedef typename TR::PredMap PredMap;
alpar@1218: //     ///\brief The type of the map that stores the last but one
alpar@1218: //     ///nodes of the %DFS paths.
alpar@1218: //     typedef typename TR::PredNodeMap PredNodeMap;
alpar@1218:     ///The type of the map indicating which nodes are reached.
alpar@1218:     typedef typename TR::ReachedMap ReachedMap;
alpar@1218:     ///The type of the map indicating which nodes are processed.
alpar@1218:     typedef typename TR::ProcessedMap ProcessedMap;
alpar@1218:     ///The type of the map that stores the dists of the nodes.
alpar@1218:     typedef typename TR::DistMap DistMap;
alpar@780:   private:
alpar@802:     /// Pointer to the underlying graph.
alpar@780:     const Graph *G;
alpar@802:     ///Pointer to the map of predecessors edges.
alpar@1218:     PredMap *_pred;
alpar@1218:     ///Indicates if \ref _pred is locally allocated (\c true) or not.
alpar@1218:     bool local_pred;
alpar@1218: //     ///Pointer to the map of predecessors nodes.
alpar@1218: //     PredNodeMap *_predNode;
alpar@1218: //     ///Indicates if \ref _predNode is locally allocated (\c true) or not.
alpar@1218: //     bool local_predNode;
alpar@802:     ///Pointer to the map of distances.
alpar@1218:     DistMap *_dist;
alpar@1218:     ///Indicates if \ref _dist is locally allocated (\c true) or not.
alpar@1218:     bool local_dist;
alpar@1218:     ///Pointer to the map of reached status of the nodes.
alpar@1218:     ReachedMap *_reached;
alpar@1218:     ///Indicates if \ref _reached is locally allocated (\c true) or not.
alpar@1218:     bool local_reached;
alpar@1218:     ///Pointer to the map of processed status of the nodes.
alpar@1218:     ProcessedMap *_processed;
alpar@1218:     ///Indicates if \ref _processed is locally allocated (\c true) or not.
alpar@1218:     bool local_processed;
alpar@780: 
alpar@1218:     std::vector<typename Graph::OutEdgeIt> _stack;
alpar@1218:     int _stack_head;
alpar@1218: //     ///The source node of the last execution.
alpar@1218: //     Node source;
alpar@780: 
alpar@1218:     ///Creates the maps if necessary.
alpar@1218:     
alpar@1218:     ///\todo Error if \c G are \c NULL.
alpar@1218:     ///\todo Better memory allocation (instead of new).
alpar@1218:     void create_maps() 
alpar@780:     {
alpar@1218:       if(!_pred) {
alpar@1218: 	local_pred = true;
alpar@1218: 	_pred = Traits::createPredMap(*G);
alpar@780:       }
alpar@1218: //       if(!_predNode) {
alpar@1218: // 	local_predNode = true;
alpar@1218: // 	_predNode = Traits::createPredNodeMap(*G);
alpar@1218: //       }
alpar@1218:       if(!_dist) {
alpar@1218: 	local_dist = true;
alpar@1218: 	_dist = Traits::createDistMap(*G);
alpar@780:       }
alpar@1218:       if(!_reached) {
alpar@1218: 	local_reached = true;
alpar@1218: 	_reached = Traits::createReachedMap(*G);
alpar@1218:       }
alpar@1218:       if(!_processed) {
alpar@1218: 	local_processed = true;
alpar@1218: 	_processed = Traits::createProcessedMap(*G);
alpar@780:       }
alpar@780:     }
alpar@780:     
alpar@1218:   public :
alpar@1218:  
alpar@1218:     ///\name Named template parameters
alpar@1218: 
alpar@1218:     ///@{
alpar@1218: 
alpar@1218:     template <class T>
alpar@1218:     struct DefPredMapTraits : public Traits {
alpar@1218:       typedef T PredMap;
alpar@1218:       static PredMap *createPredMap(const Graph &G) 
alpar@1218:       {
alpar@1218: 	throw UninitializedParameter();
alpar@1218:       }
alpar@1218:     };
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting PredMap type
alpar@1218: 
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting PredMap type
alpar@1218:     ///
alpar@1218:     template <class T>
alpar@1218:     class DefPredMap : public Dfs< Graph,
alpar@1218: 					DefPredMapTraits<T> > { };
alpar@1218:     
alpar@1218: //     template <class T>
alpar@1218: //     struct DefPredNodeMapTraits : public Traits {
alpar@1218: //       typedef T PredNodeMap;
alpar@1218: //       static PredNodeMap *createPredNodeMap(const Graph &G) 
alpar@1218: //       {
alpar@1218: // 	throw UninitializedParameter();
alpar@1218: //       }
alpar@1218: //     };
alpar@1218: //     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
alpar@1218: 
alpar@1218: //     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
alpar@1218: //     ///
alpar@1218: //     template <class T>
alpar@1218: //     class DefPredNodeMap : public Dfs< Graph,
alpar@1218: // 					    LengthMap,
alpar@1218: // 					    DefPredNodeMapTraits<T> > { };
alpar@1218:     
alpar@1218:     template <class T>
alpar@1218:     struct DefDistMapTraits : public Traits {
alpar@1218:       typedef T DistMap;
alpar@1218:       static DistMap *createDistMap(const Graph &G) 
alpar@1218:       {
alpar@1218: 	throw UninitializedParameter();
alpar@1218:       }
alpar@1218:     };
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting DistMap type
alpar@1218: 
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting DistMap type
alpar@1218:     ///
alpar@1218:     template <class T>
alpar@1218:     class DefDistMap : public Dfs< Graph,
alpar@1218: 				   DefDistMapTraits<T> > { };
alpar@1218:     
alpar@1218:     template <class T>
alpar@1218:     struct DefReachedMapTraits : public Traits {
alpar@1218:       typedef T ReachedMap;
alpar@1218:       static ReachedMap *createReachedMap(const Graph &G) 
alpar@1218:       {
alpar@1218: 	throw UninitializedParameter();
alpar@1218:       }
alpar@1218:     };
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting ReachedMap type
alpar@1218: 
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting ReachedMap type
alpar@1218:     ///
alpar@1218:     template <class T>
alpar@1218:     class DefReachedMap : public Dfs< Graph,
alpar@1218: 				      DefReachedMapTraits<T> > { };
alpar@1218:     
alpar@1218:     struct DefGraphReachedMapTraits : public Traits {
alpar@1218:       typedef typename Graph::template NodeMap<bool> ReachedMap;
alpar@1218:       static ReachedMap *createReachedMap(const Graph &G) 
alpar@1218:       {
alpar@1218: 	return new ReachedMap(G);
alpar@1218:       }
alpar@1218:     };
alpar@1218:     template <class T>
alpar@1218:     struct DefProcessedMapTraits : public Traits {
alpar@1218:       typedef T ProcessedMap;
alpar@1218:       static ProcessedMap *createProcessedMap(const Graph &G) 
alpar@1218:       {
alpar@1218: 	throw UninitializedParameter();
alpar@1218:       }
alpar@1218:     };
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
alpar@1218: 
alpar@1218:     ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
alpar@1218:     ///
alpar@1218:     template <class T>
alpar@1218:     class DefProcessedMap : public Dfs< Graph,
alpar@1218: 					DefProcessedMapTraits<T> > { };
alpar@1218:     
alpar@1218:     struct DefGraphProcessedMapTraits : public Traits {
alpar@1218:       typedef typename Graph::template NodeMap<bool> ProcessedMap;
alpar@1218:       static ProcessedMap *createProcessedMap(const Graph &G) 
alpar@1218:       {
alpar@1218: 	return new ProcessedMap(G);
alpar@1218:       }
alpar@1218:     };
alpar@1218:     ///\brief \ref named-templ-param "Named parameter"
alpar@1218:     ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
alpar@1218:     ///
alpar@1218:     ///\ref named-templ-param "Named parameter"
alpar@1218:     ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
alpar@1218:     ///If you don't set it explicitely, it will be automatically allocated.
alpar@1218:     template <class T>
alpar@1218:     class DefProcessedMapToBeDefaultMap :
alpar@1218:       public Dfs< Graph,
alpar@1218: 		  DefGraphProcessedMapTraits> { };
alpar@1218:     
alpar@1218:     ///@}
alpar@1218: 
alpar@1218:   public:      
alpar@1218:     
alpar@802:     ///Constructor.
alpar@802:     
alpar@802:     ///\param _G the graph the algorithm will run on.
alpar@911:     ///
alpar@780:     Dfs(const Graph& _G) :
alpar@780:       G(&_G),
alpar@1218:       _pred(NULL), local_pred(false),
alpar@1218: //       _predNode(NULL), local_predNode(false),
alpar@1218:       _dist(NULL), local_dist(false),
alpar@1218:       _reached(NULL), local_reached(false),
alpar@1218:       _processed(NULL), local_processed(false)
alpar@780:     { }
alpar@780:     
alpar@802:     ///Destructor.
alpar@780:     ~Dfs() 
alpar@780:     {
alpar@1218:       if(local_pred) delete _pred;
alpar@1218: //       if(local_predNode) delete _predNode;
alpar@1218:       if(local_dist) delete _dist;
alpar@1218:       if(local_reached) delete _reached;
alpar@1218:       if(local_processed) delete _processed;
alpar@780:     }
alpar@780: 
alpar@780:     ///Sets the map storing the predecessor edges.
alpar@780: 
alpar@780:     ///Sets the map storing the predecessor edges.
alpar@780:     ///If you don't use this function before calling \ref run(),
alpar@780:     ///it will allocate one. The destuctor deallocates this
alpar@780:     ///automatically allocated map, of course.
alpar@780:     ///\return <tt> (*this) </tt>
alpar@1218:     Dfs &predMap(PredMap &m) 
alpar@780:     {
alpar@1218:       if(local_pred) {
alpar@1218: 	delete _pred;
alpar@1218: 	local_pred=false;
alpar@780:       }
alpar@1218:       _pred = &m;
alpar@780:       return *this;
alpar@780:     }
alpar@780: 
alpar@1218: //     ///Sets the map storing the predecessor nodes.
alpar@780: 
alpar@1218: //     ///Sets the map storing the predecessor nodes.
alpar@1218: //     ///If you don't use this function before calling \ref run(),
alpar@1218: //     ///it will allocate one. The destuctor deallocates this
alpar@1218: //     ///automatically allocated map, of course.
alpar@1218: //     ///\return <tt> (*this) </tt>
alpar@1218: //     Dfs &predNodeMap(PredNodeMap &m) 
alpar@1218: //     {
alpar@1218: //       if(local_predNode) {
alpar@1218: // 	delete _predNode;
alpar@1218: // 	local_predNode=false;
alpar@1218: //       }
alpar@1218: //       _predNode = &m;
alpar@1218: //       return *this;
alpar@1218: //     }
alpar@780: 
alpar@780:     ///Sets the map storing the distances calculated by the algorithm.
alpar@780: 
alpar@780:     ///Sets the map storing the distances calculated by the algorithm.
alpar@780:     ///If you don't use this function before calling \ref run(),
alpar@780:     ///it will allocate one. The destuctor deallocates this
alpar@780:     ///automatically allocated map, of course.
alpar@780:     ///\return <tt> (*this) </tt>
alpar@1218:     Dfs &distMap(DistMap &m) 
alpar@780:     {
alpar@1218:       if(local_dist) {
alpar@1218: 	delete _dist;
alpar@1218: 	local_dist=false;
alpar@780:       }
alpar@1218:       _dist = &m;
alpar@780:       return *this;
alpar@780:     }
alpar@780: 
alpar@1220:     ///Sets the map indicating if a node is reached.
alpar@1220: 
alpar@1220:     ///Sets the map indicating if a node is reached.
alpar@1220:     ///If you don't use this function before calling \ref run(),
alpar@1220:     ///it will allocate one. The destuctor deallocates this
alpar@1220:     ///automatically allocated map, of course.
alpar@1220:     ///\return <tt> (*this) </tt>
alpar@1220:     Dfs &reachedMap(ReachedMap &m) 
alpar@1220:     {
alpar@1220:       if(local_reached) {
alpar@1220: 	delete _reached;
alpar@1220: 	local_reached=false;
alpar@1220:       }
alpar@1220:       _reached = &m;
alpar@1220:       return *this;
alpar@1220:     }
alpar@1220: 
alpar@1220:     ///Sets the map indicating if a node is processed.
alpar@1220: 
alpar@1220:     ///Sets the map indicating if a node is processed.
alpar@1220:     ///If you don't use this function before calling \ref run(),
alpar@1220:     ///it will allocate one. The destuctor deallocates this
alpar@1220:     ///automatically allocated map, of course.
alpar@1220:     ///\return <tt> (*this) </tt>
alpar@1220:     Dfs &processedMap(ProcessedMap &m) 
alpar@1220:     {
alpar@1220:       if(local_processed) {
alpar@1220: 	delete _processed;
alpar@1220: 	local_processed=false;
alpar@1220:       }
alpar@1220:       _processed = &m;
alpar@1220:       return *this;
alpar@1220:     }
alpar@1220: 
alpar@1218:   public:
alpar@1218:     ///\name Execution control
alpar@1218:     ///The simplest way to execute the algorithm is to use
alpar@1218:     ///one of the member functions called \c run(...).
alpar@1218:     ///\n
alpar@1218:     ///If you need more control on the execution,
alpar@1218:     ///first you must call \ref init(), then you can add several source nodes
alpar@1218:     ///with \ref addSource().
alpar@1218:     ///Finally \ref start() will perform the actual path
alpar@1218:     ///computation.
alpar@1218: 
alpar@1218:     ///@{
alpar@1218: 
alpar@1218:     ///Initializes the internal data structures.
alpar@1218: 
alpar@1218:     ///Initializes the internal data structures.
alpar@1218:     ///
alpar@1218:     void init()
alpar@1218:     {
alpar@1218:       create_maps();
alpar@1218:       _stack.resize(countNodes(*G));
alpar@1218:       _stack_head=-1;
alpar@780:       for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
alpar@1218: 	_pred->set(u,INVALID);
alpar@1218: 	// _predNode->set(u,INVALID);
alpar@1218: 	_reached->set(u,false);
alpar@1218: 	_processed->set(u,false);
alpar@780:       }
alpar@780:     }
alpar@780:     
alpar@1218:     ///Adds a new source node.
alpar@780: 
alpar@1218:     ///Adds a new source node to the set of nodes to be processed.
alpar@1218:     ///
alpar@1218:     ///\bug dist's are wrong (or at least strange) in case of multiple sources.
alpar@1218:     void addSource(Node s)
alpar@1218:     {
alpar@1218:       if(!(*_reached)[s])
alpar@1218: 	{
alpar@1218: 	  _reached->set(s,true);
alpar@1218: 	  _pred->set(s,INVALID);
alpar@1218: 	  // _predNode->set(u,INVALID);
alpar@1218: 	  _stack[++_stack_head]=OutEdgeIt(*G,s);
alpar@1218: 	  _dist->set(s,_stack_head);
alpar@1218: 	}
alpar@1218:     }
alpar@1218:     
alpar@1218:     ///Processes the next node.
alpar@1218: 
alpar@1218:     ///Processes the next node.
alpar@1218:     ///
alpar@1218:     ///\warning The stack must not be empty!
alpar@1218:     void processNextEdge()
alpar@1218:     { 
alpar@1218:       Node m;
alpar@1218:       Edge e=_stack[_stack_head];
alpar@1218:       if(!(*_reached)[m=G->target(e)]) {
alpar@1218: 	_pred->set(m,e);
alpar@1218: 	_reached->set(m,true);
alpar@1218: 	//	  _pred_node->set(m,G->source(e));
alpar@1233: 	++_stack_head;
alpar@1233: 	_stack[_stack_head] = OutEdgeIt(*G, m);
alpar@1218: 	_dist->set(m,_stack_head);
alpar@1218:       }
alpar@1218:       else {
alpar@1218: 	Node n;
alpar@1218: 	while(_stack_head>=0 &&
alpar@1218: 	      (n=G->source(_stack[_stack_head]),
alpar@1218: 	       ++_stack[_stack_head]==INVALID))
alpar@1218: 	  {
alpar@1218: 	    _processed->set(n,true);
alpar@1218: 	    --_stack_head;
alpar@1218: 	  }
alpar@1218:       }
alpar@1218:     }
alpar@1218:       
alpar@1218:     ///\brief Returns \c false if there are nodes
alpar@1218:     ///to be processed in the queue
alpar@1218:     ///
alpar@1218:     ///Returns \c false if there are nodes
alpar@1218:     ///to be processed in the queue
alpar@1218:     bool emptyQueue() { return _stack_head<0; }
alpar@1218:     ///Returns the number of the nodes to be processed.
alpar@1218:     
alpar@1218:     ///Returns the number of the nodes to be processed in the queue.
alpar@1218:     ///
alpar@1218:     int queueSize() { return _stack_head+1; }
alpar@1218:     
alpar@1218:     ///Executes the algorithm.
alpar@1218: 
alpar@1218:     ///Executes the algorithm.
alpar@1218:     ///
alpar@1218:     ///\pre init() must be called and at least one node should be added
alpar@1218:     ///with addSource() before using this function.
alpar@1218:     ///
alpar@1218:     ///This method runs the %DFS algorithm from the root node(s)
alpar@1218:     ///in order to
alpar@1218:     ///compute the
alpar@1218:     ///%DFS path to each node. The algorithm computes
alpar@1218:     ///- The %DFS tree.
alpar@1218:     ///- The distance of each node from the root(s).
alpar@1218:     ///
alpar@1218:     void start()
alpar@1218:     {
alpar@1218:       while ( !emptyQueue() ) processNextEdge();
alpar@1218:     }
alpar@1218:     
alpar@1218:     ///Executes the algorithm until \c dest is reached.
alpar@1218: 
alpar@1218:     ///Executes the algorithm until \c dest is reached.
alpar@1218:     ///
alpar@1218:     ///\pre init() must be called and at least one node should be added
alpar@1218:     ///with addSource() before using this function.
alpar@1218:     ///
alpar@1218:     ///This method runs the %DFS algorithm from the root node(s)
alpar@1218:     ///in order to
alpar@1218:     ///compute the
alpar@1218:     ///%DFS path to \c dest. The algorithm computes
alpar@1218:     ///- The %DFS path to \c  dest.
alpar@1218:     ///- The distance of \c dest from the root(s).
alpar@1218:     ///
alpar@1218:     void start(Node dest)
alpar@1218:     {
alpar@1233:       while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest ) 
alpar@1233: 	processNextEdge();
alpar@1218:     }
alpar@1218:     
alpar@1218:     ///Executes the algorithm until a condition is met.
alpar@1218: 
alpar@1218:     ///Executes the algorithm until a condition is met.
alpar@1218:     ///
alpar@1218:     ///\pre init() must be called and at least one node should be added
alpar@1218:     ///with addSource() before using this function.
alpar@1218:     ///
alpar@1233:     ///\param nm must be a bool (or convertible) edge map. The algorithm
alpar@1233:     ///will stop when it reaches a edge \c v with <tt>nm[v]==true</tt>.
alpar@1233:     ///\warning Contrary to \ref Dfs and \ref Dijkstra, \c mn is an edge map,
alpar@1233:     ///not a node map.
alpar@1218:     template<class NM>
alpar@1218:       void start(const NM &nm)
alpar@1218:       {
alpar@1233: 	while ( !emptyQueue() && !nm[_stack[_stack_head]] ) processNextEdge();
alpar@1218:       }
alpar@1218:     
alpar@1218:     ///Runs %DFS algorithm from node \c s.
alpar@1218:     
alpar@1218:     ///This method runs the %DFS algorithm from a root node \c s
alpar@1218:     ///in order to
alpar@1218:     ///compute the
alpar@1218:     ///%DFS path to each node. The algorithm computes
alpar@1218:     ///- The %DFS tree.
alpar@1218:     ///- The distance of each node from the root.
alpar@1218:     ///
alpar@1218:     ///\note d.run(s) is just a shortcut of the following code.
alpar@1218:     ///\code
alpar@1218:     ///  d.init();
alpar@1218:     ///  d.addSource(s);
alpar@1218:     ///  d.start();
alpar@1218:     ///\endcode
alpar@1218:     void run(Node s) {
alpar@1218:       init();
alpar@1218:       addSource(s);
alpar@1218:       start();
alpar@1218:     }
alpar@1218:     
alpar@1218:     ///Finds the %DFS path between \c s and \c t.
alpar@1218:     
alpar@1218:     ///Finds the %DFS path between \c s and \c t.
alpar@1218:     ///
alpar@1218:     ///\return The length of the %DFS s---t path if there exists one,
alpar@1218:     ///0 otherwise.
alpar@1218:     ///\note Apart from the return value, d.run(s) is
alpar@1218:     ///just a shortcut of the following code.
alpar@1218:     ///\code
alpar@1218:     ///  d.init();
alpar@1218:     ///  d.addSource(s);
alpar@1218:     ///  d.start(t);
alpar@1218:     ///\endcode
alpar@1218:     int run(Node s,Node t) {
alpar@1218:       init();
alpar@1218:       addSource(s);
alpar@1218:       start(t);
alpar@1233:       return reached(t)?_stack_head+1:0;
alpar@1218:     }
alpar@1218:     
alpar@1218:     ///@}
alpar@1218: 
alpar@1218:     ///\name Query Functions
alpar@1218:     ///The result of the %DFS algorithm can be obtained using these
alpar@1218:     ///functions.\n
alpar@1218:     ///Before the use of these functions,
alpar@1218:     ///either run() or start() must be called.
alpar@1218:     
alpar@1218:     ///@{
alpar@1218: 
alpar@1283:     ///Copies the path to \c t on the DFS tree into \c p
alpar@1283:     
alpar@1283:     ///This function copies the path on the DFS tree to \c t into \c p.
alpar@1283:     ///If it \c \t is a source itself or unreachable, then it does not
alpar@1283:     ///alter \c p.
alpar@1283:     ///\todo Is it the right way to handle unreachable nodes?
alpar@1283:     ///\return Returns \c true if a path to \c t was actually copied to \c p,
alpar@1283:     ///\c false otherwise.
alpar@1283:     ///\sa DirPath
alpar@1283:     template<class P>
alpar@1283:     bool getPath(P &p,Node t) 
alpar@1283:     {
alpar@1283:       if(reached(t)) {
alpar@1283: 	p.clear();
alpar@1283: 	typename P::Builder b(p);
alpar@1283: 	for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
alpar@1283: 	  b.pushFront(pred(t));
alpar@1283: 	b.commit();
alpar@1283: 	return true;
alpar@1283:       }
alpar@1283:       return false;
alpar@1283:     }
alpar@1283: 
alpar@1218:     ///The distance of a node from the root(s).
alpar@1218: 
alpar@1218:     ///Returns the distance of a node from the root(s).
alpar@780:     ///\pre \ref run() must be called before using this function.
alpar@1218:     ///\warning If node \c v in unreachable from the root(s) the return value
alpar@780:     ///of this funcion is undefined.
alpar@1218:     int dist(Node v) const { return (*_dist)[v]; }
alpar@780: 
alpar@1218:     ///Returns the 'previous edge' of the %DFS tree.
alpar@780: 
alpar@1218:     ///For a node \c v it returns the 'previous edge'
alpar@1218:     ///of the %DFS path,
alpar@1218:     ///i.e. it returns the last edge of a %DFS path from the root(s) to \c
alpar@780:     ///v. It is \ref INVALID
alpar@1218:     ///if \c v is unreachable from the root(s) or \c v is a root. The
alpar@781:     ///%DFS tree used here is equal to the %DFS tree used in
alpar@1218:     ///\ref predNode(Node v).
alpar@1218:     ///\pre Either \ref run() or \ref start() must be called before using
alpar@780:     ///this function.
alpar@1218:     ///\todo predEdge could be a better name.
alpar@1218:     Edge pred(Node v) const { return (*_pred)[v];}
alpar@780: 
alpar@781:     ///Returns the 'previous node' of the %DFS tree.
alpar@780: 
alpar@1218:     ///For a node \c v it returns the 'previous node'
alpar@1218:     ///of the %DFS tree,
alpar@1218:     ///i.e. it returns the last but one node from a %DFS path from the
alpar@1218:     ///root(a) to \c /v.
alpar@1218:     ///It is INVALID if \c v is unreachable from the root(s) or
alpar@1218:     ///if \c v itself a root.
alpar@1218:     ///The %DFS tree used here is equal to the %DFS
alpar@1218:     ///tree used in \ref pred(Node v).
alpar@1218:     ///\pre Either \ref run() or \ref start() must be called before
alpar@780:     ///using this function.
alpar@1218:     Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
alpar@1218: 				  G->source((*_pred)[v]); }
alpar@780:     
alpar@1218:     ///Returns a reference to the NodeMap of distances.
alpar@1218: 
alpar@1218:     ///Returns a reference to the NodeMap of distances.
alpar@1218:     ///\pre Either \ref run() or \ref init() must
alpar@780:     ///be called before using this function.
alpar@1218:     const DistMap &distMap() const { return *_dist;}
alpar@780:  
alpar@1218:     ///Returns a reference to the %DFS edge-tree map.
alpar@780: 
alpar@780:     ///Returns a reference to the NodeMap of the edges of the
alpar@781:     ///%DFS tree.
alpar@1218:     ///\pre Either \ref run() or \ref init()
alpar@1218:     ///must be called before using this function.
alpar@1218:     const PredMap &predMap() const { return *_pred;}
alpar@780:  
alpar@1218: //     ///Returns a reference to the map of nodes of %DFS paths.
alpar@780: 
alpar@1218: //     ///Returns a reference to the NodeMap of the last but one nodes of the
alpar@1218: //     ///%DFS tree.
alpar@1218: //     ///\pre \ref run() must be called before using this function.
alpar@1218: //     const PredNodeMap &predNodeMap() const { return *_predNode;}
alpar@780: 
alpar@780:     ///Checks if a node is reachable from the root.
alpar@780: 
alpar@780:     ///Returns \c true if \c v is reachable from the root.
alpar@1218:     ///\warning The source nodes are inditated as unreached.
alpar@1218:     ///\pre Either \ref run() or \ref start()
alpar@1218:     ///must be called before using this function.
alpar@780:     ///
alpar@1218:     bool reached(Node v) { return (*_reached)[v]; }
alpar@1218:     
alpar@1218:     ///@}
alpar@1218:   };
alpar@1218: 
alpar@1218:   ///Default traits class of Dfs function.
alpar@1218: 
alpar@1218:   ///Default traits class of Dfs function.
alpar@1218:   ///\param GR Graph type.
alpar@1218:   template<class GR>
alpar@1218:   struct DfsWizardDefaultTraits
alpar@1218:   {
alpar@1218:     ///The graph type the algorithm runs on. 
alpar@1218:     typedef GR Graph;
alpar@1218:     ///\brief The type of the map that stores the last
alpar@1218:     ///edges of the %DFS paths.
alpar@1218:     /// 
alpar@1218:     ///The type of the map that stores the last
alpar@1218:     ///edges of the %DFS paths.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@780:     ///
alpar@1218:     typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
alpar@1218:     ///Instantiates a PredMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref PredMap. 
alpar@1218:     ///\param G is the graph, to which we would like to define the PredMap.
alpar@1218:     ///\todo The graph alone may be insufficient to initialize
alpar@1367:     static PredMap *createPredMap(const GR &) 
alpar@1218:     {
alpar@1218:       return new PredMap();
alpar@1218:     }
alpar@1218: //     ///\brief The type of the map that stores the last but one
alpar@1218: //     ///nodes of the %DFS paths.
alpar@1218: //     ///
alpar@1218: //     ///The type of the map that stores the last but one
alpar@1218: //     ///nodes of the %DFS paths.
alpar@1218: //     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218: //     ///
alpar@1218: //     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
alpar@1218: //     ///Instantiates a PredNodeMap.
alpar@1218:     
alpar@1218: //     ///This function instantiates a \ref PredNodeMap. 
alpar@1218: //     ///\param G is the graph, to which
alpar@1218: //     ///we would like to define the \ref PredNodeMap
alpar@1218: //     static PredNodeMap *createPredNodeMap(const GR &G)
alpar@1218: //     {
alpar@1218: //       return new PredNodeMap();
alpar@1218: //     }
alpar@1218: 
alpar@1218:     ///The type of the map that indicates which nodes are processed.
alpar@1218:  
alpar@1218:     ///The type of the map that indicates which nodes are processed.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///\todo named parameter to set this type, function to read and write.
alpar@1218:     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
alpar@1218:     ///Instantiates a ProcessedMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref ProcessedMap. 
alpar@1218:     ///\param G is the graph, to which
alpar@1218:     ///we would like to define the \ref ProcessedMap
alpar@1367:     static ProcessedMap *createProcessedMap(const GR &)
alpar@1218:     {
alpar@1218:       return new ProcessedMap();
alpar@1218:     }
alpar@1218:     ///The type of the map that indicates which nodes are reached.
alpar@1218:  
alpar@1218:     ///The type of the map that indicates which nodes are reached.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///\todo named parameter to set this type, function to read and write.
alpar@1218:     typedef typename Graph::template NodeMap<bool> ReachedMap;
alpar@1218:     ///Instantiates a ReachedMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref ReachedMap. 
alpar@1218:     ///\param G is the graph, to which
alpar@1218:     ///we would like to define the \ref ReachedMap.
alpar@1218:     static ReachedMap *createReachedMap(const GR &G)
alpar@1218:     {
alpar@1218:       return new ReachedMap(G);
alpar@1218:     }
alpar@1218:     ///The type of the map that stores the dists of the nodes.
alpar@1218:  
alpar@1218:     ///The type of the map that stores the dists of the nodes.
alpar@1218:     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
alpar@1218:     ///
alpar@1218:     typedef NullMap<typename Graph::Node,int> DistMap;
alpar@1218:     ///Instantiates a DistMap.
alpar@1218:  
alpar@1218:     ///This function instantiates a \ref DistMap. 
alpar@1218:     ///\param G is the graph, to which we would like to define the \ref DistMap
alpar@1367:     static DistMap *createDistMap(const GR &)
alpar@1218:     {
alpar@1218:       return new DistMap();
alpar@1218:     }
alpar@1218:   };
alpar@1218:   
alpar@1218:   /// Default traits used by \ref DfsWizard
alpar@1218: 
alpar@1218:   /// To make it easier to use Dfs algorithm
alpar@1218:   ///we have created a wizard class.
alpar@1218:   /// This \ref DfsWizard class needs default traits,
alpar@1218:   ///as well as the \ref Dfs class.
alpar@1218:   /// The \ref DfsWizardBase is a class to be the default traits of the
alpar@1218:   /// \ref DfsWizard class.
alpar@1218:   template<class GR>
alpar@1218:   class DfsWizardBase : public DfsWizardDefaultTraits<GR>
alpar@1218:   {
alpar@1218: 
alpar@1218:     typedef DfsWizardDefaultTraits<GR> Base;
alpar@1218:   protected:
alpar@1218:     /// Type of the nodes in the graph.
alpar@1218:     typedef typename Base::Graph::Node Node;
alpar@1218: 
alpar@1218:     /// Pointer to the underlying graph.
alpar@1218:     void *_g;
alpar@1218:     ///Pointer to the map of reached nodes.
alpar@1218:     void *_reached;
alpar@1218:     ///Pointer to the map of processed nodes.
alpar@1218:     void *_processed;
alpar@1218:     ///Pointer to the map of predecessors edges.
alpar@1218:     void *_pred;
alpar@1218: //     ///Pointer to the map of predecessors nodes.
alpar@1218: //     void *_predNode;
alpar@1218:     ///Pointer to the map of distances.
alpar@1218:     void *_dist;
alpar@1218:     ///Pointer to the source node.
alpar@1218:     Node _source;
alpar@1218:     
alpar@1218:     public:
alpar@1218:     /// Constructor.
alpar@1218:     
alpar@1218:     /// This constructor does not require parameters, therefore it initiates
alpar@1218:     /// all of the attributes to default values (0, INVALID).
alpar@1218:     DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
alpar@1218: // 			   _predNode(0),
alpar@1218: 			   _dist(0), _source(INVALID) {}
alpar@1218: 
alpar@1218:     /// Constructor.
alpar@1218:     
alpar@1218:     /// This constructor requires some parameters,
alpar@1218:     /// listed in the parameters list.
alpar@1218:     /// Others are initiated to 0.
alpar@1218:     /// \param g is the initial value of  \ref _g
alpar@1218:     /// \param s is the initial value of  \ref _source
alpar@1218:     DfsWizardBase(const GR &g, Node s=INVALID) :
alpar@1218:       _g((void *)&g), _reached(0), _processed(0), _pred(0),
alpar@1218: //       _predNode(0),
alpar@1218:       _dist(0), _source(s) {}
alpar@1218: 
alpar@1218:   };
alpar@1218:   
alpar@1218:   /// A class to make the usage of Dfs algorithm easier
alpar@1218: 
alpar@1218:   /// This class is created to make it easier to use Dfs algorithm.
alpar@1218:   /// It uses the functions and features of the plain \ref Dfs,
alpar@1218:   /// but it is much simpler to use it.
alpar@1218:   ///
alpar@1218:   /// Simplicity means that the way to change the types defined
alpar@1218:   /// in the traits class is based on functions that returns the new class
alpar@1218:   /// and not on templatable built-in classes.
alpar@1218:   /// When using the plain \ref Dfs
alpar@1218:   /// the new class with the modified type comes from
alpar@1218:   /// the original class by using the ::
alpar@1218:   /// operator. In the case of \ref DfsWizard only
alpar@1218:   /// a function have to be called and it will
alpar@1218:   /// return the needed class.
alpar@1218:   ///
alpar@1218:   /// It does not have own \ref run method. When its \ref run method is called
alpar@1218:   /// it initiates a plain \ref Dfs class, and calls the \ref Dfs::run
alpar@1218:   /// method of it.
alpar@1218:   template<class TR>
alpar@1218:   class DfsWizard : public TR
alpar@1218:   {
alpar@1218:     typedef TR Base;
alpar@1218: 
alpar@1218:     ///The type of the underlying graph.
alpar@1218:     typedef typename TR::Graph Graph;
alpar@1218:     //\e
alpar@1218:     typedef typename Graph::Node Node;
alpar@1218:     //\e
alpar@1218:     typedef typename Graph::NodeIt NodeIt;
alpar@1218:     //\e
alpar@1218:     typedef typename Graph::Edge Edge;
alpar@1218:     //\e
alpar@1218:     typedef typename Graph::OutEdgeIt OutEdgeIt;
alpar@1218:     
alpar@1218:     ///\brief The type of the map that stores
alpar@1218:     ///the reached nodes
alpar@1218:     typedef typename TR::ReachedMap ReachedMap;
alpar@1218:     ///\brief The type of the map that stores
alpar@1218:     ///the processed nodes
alpar@1218:     typedef typename TR::ProcessedMap ProcessedMap;
alpar@1218:     ///\brief The type of the map that stores the last
alpar@1218:     ///edges of the %DFS paths.
alpar@1218:     typedef typename TR::PredMap PredMap;
alpar@1218: //     ///\brief The type of the map that stores the last but one
alpar@1218: //     ///nodes of the %DFS paths.
alpar@1218: //     typedef typename TR::PredNodeMap PredNodeMap;
alpar@1218:     ///The type of the map that stores the dists of the nodes.
alpar@1218:     typedef typename TR::DistMap DistMap;
alpar@1218: 
alpar@1218: public:
alpar@1218:     /// Constructor.
alpar@1218:     DfsWizard() : TR() {}
alpar@1218: 
alpar@1218:     /// Constructor that requires parameters.
alpar@1218: 
alpar@1218:     /// Constructor that requires parameters.
alpar@1218:     /// These parameters will be the default values for the traits class.
alpar@1218:     DfsWizard(const Graph &g, Node s=INVALID) :
alpar@1218:       TR(g,s) {}
alpar@1218: 
alpar@1218:     ///Copy constructor
alpar@1218:     DfsWizard(const TR &b) : TR(b) {}
alpar@1218: 
alpar@1218:     ~DfsWizard() {}
alpar@1218: 
alpar@1218:     ///Runs Dfs algorithm from a given node.
alpar@1218:     
alpar@1218:     ///Runs Dfs algorithm from a given node.
alpar@1218:     ///The node can be given by the \ref source function.
alpar@1218:     void run()
alpar@1218:     {
alpar@1218:       if(Base::_source==INVALID) throw UninitializedParameter();
alpar@1218:       Dfs<Graph,TR> alg(*(Graph*)Base::_g);
alpar@1218:       if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
alpar@1218:       if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
alpar@1218:       if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
alpar@1218: //       if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
alpar@1218:       if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
alpar@1218:       alg.run(Base::_source);
alpar@1218:     }
alpar@1218: 
alpar@1218:     ///Runs Dfs algorithm from the given node.
alpar@1218: 
alpar@1218:     ///Runs Dfs algorithm from the given node.
alpar@1218:     ///\param s is the given source.
alpar@1218:     void run(Node s)
alpar@1218:     {
alpar@1218:       Base::_source=s;
alpar@1218:       run();
alpar@1218:     }
alpar@1218: 
alpar@1218:     template<class T>
alpar@1218:     struct DefPredMapBase : public Base {
alpar@1218:       typedef T PredMap;
alpar@1367:       static PredMap *createPredMap(const Graph &) { return 0; };
alpar@1236:       DefPredMapBase(const TR &b) : TR(b) {}
alpar@1218:     };
alpar@1218:     
alpar@1218:     ///\brief \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting PredMap type
alpar@1218:     ///
alpar@1218:     /// \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting PredMap type
alpar@1218:     ///
alpar@1218:     template<class T>
alpar@1218:     DfsWizard<DefPredMapBase<T> > predMap(const T &t) 
alpar@1218:     {
alpar@1218:       Base::_pred=(void *)&t;
alpar@1218:       return DfsWizard<DefPredMapBase<T> >(*this);
alpar@1218:     }
alpar@1218:     
alpar@1218:  
alpar@1218:     template<class T>
alpar@1218:     struct DefReachedMapBase : public Base {
alpar@1218:       typedef T ReachedMap;
alpar@1367:       static ReachedMap *createReachedMap(const Graph &) { return 0; };
alpar@1236:       DefReachedMapBase(const TR &b) : TR(b) {}
alpar@1218:     };
alpar@1218:     
alpar@1218:     ///\brief \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting ReachedMap
alpar@1218:     ///
alpar@1218:     /// \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting ReachedMap
alpar@1218:     ///
alpar@1218:     template<class T>
alpar@1218:     DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) 
alpar@1218:     {
alpar@1218:       Base::_pred=(void *)&t;
alpar@1218:       return DfsWizard<DefReachedMapBase<T> >(*this);
alpar@1218:     }
alpar@1218:     
alpar@1218: 
alpar@1218:     template<class T>
alpar@1218:     struct DefProcessedMapBase : public Base {
alpar@1218:       typedef T ProcessedMap;
alpar@1367:       static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
alpar@1236:       DefProcessedMapBase(const TR &b) : TR(b) {}
alpar@1218:     };
alpar@1218:     
alpar@1218:     ///\brief \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting ProcessedMap
alpar@1218:     ///
alpar@1218:     /// \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting ProcessedMap
alpar@1218:     ///
alpar@1218:     template<class T>
alpar@1218:     DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) 
alpar@1218:     {
alpar@1218:       Base::_pred=(void *)&t;
alpar@1218:       return DfsWizard<DefProcessedMapBase<T> >(*this);
alpar@1218:     }
alpar@1218:     
alpar@1218: 
alpar@1218: //     template<class T>
alpar@1218: //     struct DefPredNodeMapBase : public Base {
alpar@1218: //       typedef T PredNodeMap;
alpar@1218: //       static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
alpar@1236: //       DefPredNodeMapBase(const TR &b) : TR(b) {}
alpar@1218: //     };
alpar@1218:     
alpar@1218: //     ///\brief \ref named-templ-param "Named parameter"
alpar@1218: //     ///function for setting PredNodeMap type
alpar@1218: //     ///
alpar@1218: //     /// \ref named-templ-param "Named parameter"
alpar@1218: //     ///function for setting PredNodeMap type
alpar@1218: //     ///
alpar@1218: //     template<class T>
alpar@1218: //     DfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t) 
alpar@1218: //     {
alpar@1218: //       Base::_predNode=(void *)&t;
alpar@1218: //       return DfsWizard<DefPredNodeMapBase<T> >(*this);
alpar@1218: //     }
alpar@1218:    
alpar@1218:     template<class T>
alpar@1218:     struct DefDistMapBase : public Base {
alpar@1218:       typedef T DistMap;
alpar@1367:       static DistMap *createDistMap(const Graph &) { return 0; };
alpar@1236:       DefDistMapBase(const TR &b) : TR(b) {}
alpar@1218:     };
alpar@1218:     
alpar@1218:     ///\brief \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting DistMap type
alpar@1218:     ///
alpar@1218:     /// \ref named-templ-param "Named parameter"
alpar@1218:     ///function for setting DistMap type
alpar@1218:     ///
alpar@1218:     template<class T>
alpar@1218:     DfsWizard<DefDistMapBase<T> > distMap(const T &t) 
alpar@1218:     {
alpar@1218:       Base::_dist=(void *)&t;
alpar@1218:       return DfsWizard<DefDistMapBase<T> >(*this);
alpar@1218:     }
alpar@1218:     
alpar@1218:     /// Sets the source node, from which the Dfs algorithm runs.
alpar@1218: 
alpar@1218:     /// Sets the source node, from which the Dfs algorithm runs.
alpar@1218:     /// \param s is the source node.
alpar@1218:     DfsWizard<TR> &source(Node s) 
alpar@1218:     {
alpar@1218:       Base::_source=s;
alpar@1218:       return *this;
alpar@1218:     }
alpar@780:     
alpar@780:   };
alpar@780:   
alpar@1218:   ///Function type interface for Dfs algorithm.
alpar@1218: 
alpar@1218:   /// \ingroup flowalgs
alpar@1218:   ///Function type interface for Dfs algorithm.
alpar@1218:   ///
alpar@1218:   ///This function also has several
alpar@1218:   ///\ref named-templ-func-param "named parameters",
alpar@1218:   ///they are declared as the members of class \ref DfsWizard.
alpar@1218:   ///The following
alpar@1218:   ///example shows how to use these parameters.
alpar@1218:   ///\code
alpar@1218:   ///  dfs(g,source).predMap(preds).run();
alpar@1218:   ///\endcode
alpar@1218:   ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
alpar@1218:   ///to the end of the parameter list.
alpar@1218:   ///\sa DfsWizard
alpar@1218:   ///\sa Dfs
alpar@1218:   template<class GR>
alpar@1218:   DfsWizard<DfsWizardBase<GR> >
alpar@1218:   dfs(const GR &g,typename GR::Node s=INVALID)
alpar@1218:   {
alpar@1218:     return DfsWizard<DfsWizardBase<GR> >(g,s);
alpar@1218:   }
alpar@1218: 
alpar@921: } //END OF NAMESPACE LEMON
alpar@780: 
alpar@780: #endif
alpar@780: