/* -*- mode: C++; indent-tabs-mode: nil; -*-
* This file is a part of LEMON, a generic C++ optimization library.
* Copyright (C) 2003-2008
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
* (Egervary Research Group on Combinatorial Optimization, EGRES).
* Permission to use, modify and distribute this software is granted
* provided that this copyright notice appears in all copies. For
* precise terms see the accompanying LICENSE file.
* This software is provided "AS IS" with no warranty of any kind,
* express or implied, and with no claim as to its suitability for any
#include <lemon/list_graph.h>
#include <lemon/bits/path_dump.h>
#include <lemon/assert.h>
///Default traits class of Dfs class.
///Default traits class of Dfs class.
///\tparam GR Digraph type.
///The type of the digraph the algorithm runs on.
///\brief The type of the map that stores the predecessor
///arcs of the %DFS paths.
///The type of the map that stores the predecessor
///arcs of the %DFS paths.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
///Instantiates a \ref PredMap.
///This function instantiates a \ref PredMap.
///\param g is the digraph, to which we would like to define the
///\todo The digraph alone may be insufficient to initialize
static PredMap *createPredMap(const Digraph &g)
///The type of the map that indicates which nodes are processed.
///The type of the map that indicates which nodes are processed.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
///By default it is a NullMap.
typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
///Instantiates a \ref ProcessedMap.
///This function instantiates a \ref ProcessedMap.
///\param g is the digraph, to which
///we would like to define the \ref ProcessedMap
static ProcessedMap *createProcessedMap(const Digraph &g)
static ProcessedMap *createProcessedMap(const Digraph &)
return new ProcessedMap();
///The type of the map that indicates which nodes are reached.
///The type of the map that indicates which nodes are reached.
///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
typedef typename Digraph::template NodeMap<bool> ReachedMap;
///Instantiates a \ref ReachedMap.
///This function instantiates a \ref ReachedMap.
///\param g is the digraph, to which
///we would like to define the \ref ReachedMap.
static ReachedMap *createReachedMap(const Digraph &g)
return new ReachedMap(g);
///The type of the map that stores the distances of the nodes.
///The type of the map that stores the distances of the nodes.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
typedef typename Digraph::template NodeMap<int> DistMap;
///Instantiates a \ref DistMap.
///This function instantiates a \ref DistMap.
///\param g is the digraph, to which we would like to define the
static DistMap *createDistMap(const Digraph &g)
///This class provides an efficient implementation of the %DFS algorithm.
///There is also a \ref dfs() "function-type interface" for the DFS
///algorithm, which is convenient in the simplier cases and it can be
///\tparam GR The type of the digraph the algorithm runs on.
///The default value is \ref ListDigraph. The value of GR is not used
///directly by \ref Dfs, it is only passed to \ref DfsDefaultTraits.
///\tparam TR Traits class to set various data types used by the algorithm.
///The default traits class is
///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
///See \ref DfsDefaultTraits for the documentation of
template <typename GR=ListDigraph,
typename TR=DfsDefaultTraits<GR> >
///\ref Exception for uninitialized parameters.
///This error represents problems in the initialization of the
///parameters of the algorithm.
class UninitializedParameter : public lemon::UninitializedParameter {
virtual const char* what() const throw() {
return "lemon::Dfs::UninitializedParameter";
///The type of the digraph the algorithm runs on.
typedef typename TR::Digraph Digraph;
///\brief The type of the map that stores the predecessor arcs of the
typedef typename TR::PredMap PredMap;
///The type of the map that stores the distances of the nodes.
typedef typename TR::DistMap DistMap;
///The type of the map that indicates which nodes are reached.
typedef typename TR::ReachedMap ReachedMap;
///The type of the map that indicates which nodes are processed.
typedef typename TR::ProcessedMap ProcessedMap;
///The type of the paths.
typedef PredMapPath<Digraph, PredMap> Path;
typedef typename Digraph::Node Node;
typedef typename Digraph::NodeIt NodeIt;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::OutArcIt OutArcIt;
//Pointer to the underlying digraph.
//Pointer to the map of predecessor arcs.
//Indicates if _pred is locally allocated (true) or not.
//Pointer to the map of distances.
//Indicates if _dist is locally allocated (true) or not.
//Pointer to the map of reached status of the nodes.
//Indicates if _reached is locally allocated (true) or not.
//Pointer to the map of processed status of the nodes.
ProcessedMap *_processed;
//Indicates if _processed is locally allocated (true) or not.
std::vector<typename Digraph::OutArcIt> _stack;
///Creates the maps if necessary.
///\todo Better memory allocation (instead of new).
_pred = Traits::createPredMap(*G);
_dist = Traits::createDistMap(*G);
_reached = Traits::createReachedMap(*G);
_processed = Traits::createProcessedMap(*G);
///\name Named template parameters
struct SetPredMapTraits : public Traits {
static PredMap *createPredMap(const Digraph &)
throw UninitializedParameter();
///\brief \ref named-templ-param "Named parameter" for setting
///\ref named-templ-param "Named parameter" for setting
struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
struct SetDistMapTraits : public Traits {
static DistMap *createDistMap(const Digraph &)
throw UninitializedParameter();
///\brief \ref named-templ-param "Named parameter" for setting
///\ref named-templ-param "Named parameter" for setting
struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
struct SetReachedMapTraits : public Traits {
static ReachedMap *createReachedMap(const Digraph &)
throw UninitializedParameter();
///\brief \ref named-templ-param "Named parameter" for setting
///\ref named-templ-param "Named parameter" for setting
struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
struct SetProcessedMapTraits : public Traits {
static ProcessedMap *createProcessedMap(const Digraph &)
throw UninitializedParameter();
///\brief \ref named-templ-param "Named parameter" for setting
///\ref ProcessedMap type.
///\ref named-templ-param "Named parameter" for setting
///\ref ProcessedMap type.
struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
struct SetStandardProcessedMapTraits : public Traits {
typedef typename Digraph::template NodeMap<bool> ProcessedMap;
static ProcessedMap *createProcessedMap(const Digraph &g)
return new ProcessedMap(g);
///\brief \ref named-templ-param "Named parameter" for setting
///\ref ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
///\ref named-templ-param "Named parameter" for setting
///\ref ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
///If you don't set it explicitly, it will be automatically allocated.
struct SetStandardProcessedMap :
public Dfs< Digraph, SetStandardProcessedMapTraits > {
typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
///\param g The digraph the algorithm runs on.
_pred(NULL), local_pred(false),
_dist(NULL), local_dist(false),
_reached(NULL), local_reached(false),
_processed(NULL), local_processed(false)
if(local_pred) delete _pred;
if(local_dist) delete _dist;
if(local_reached) delete _reached;
if(local_processed) delete _processed;
///Sets the map that stores the predecessor arcs.
///Sets the map that stores the predecessor arcs.
///If you don't use this function before calling \ref run(),
///it will allocate one. The destructor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
///Sets the map that indicates which nodes are reached.
///Sets the map that indicates which nodes are reached.
///If you don't use this function before calling \ref run(),
///it will allocate one. The destructor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
Dfs &reachedMap(ReachedMap &m)
///Sets the map that indicates which nodes are processed.
///Sets the map that indicates which nodes are processed.
///If you don't use this function before calling \ref run(),
///it will allocate one. The destructor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
Dfs &processedMap(ProcessedMap &m)
///Sets the map that stores the distances of the nodes.
///Sets the map that stores the distances of the nodes calculated by
///If you don't use this function before calling \ref run(),
///it will allocate one. The destructor deallocates this
///automatically allocated map, of course.
///\return <tt> (*this) </tt>
///\name Execution control
///The simplest way to execute the algorithm is to use
///one of the member functions called \ref lemon::Dfs::run() "run()".
///If you need more control on the execution, first you must call
///\ref lemon::Dfs::init() "init()", then you can add a source node
///with \ref lemon::Dfs::addSource() "addSource()".
///Finally \ref lemon::Dfs::start() "start()" will perform the
///actual path computation.
///Initializes the internal data structures.
///Initializes the internal data structures.
_stack.resize(countNodes(*G));
for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
_processed->set(u,false);
///Adds a new source node.
///Adds a new source node to the set of nodes to be processed.
///\pre The stack must be empty. (Otherwise the algorithm gives
///\warning Distances will be wrong (or at least strange) in case of
LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
_dist->set(s,_stack_head);
///Processes the next arc.
///Processes the next arc.
///\return The processed arc.
///\pre The stack must not be empty.
Arc e=_stack[_stack_head];
if(!(*_reached)[m=G->target(e)]) {
_stack[_stack_head] = OutArcIt(*G, m);
_dist->set(m,_stack_head);
while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
m=G->source(_stack[_stack_head]);
///Next arc to be processed.
///Next arc to be processed.
///\return The next arc to be processed or \c INVALID if the stack
return _stack_head>=0?_stack[_stack_head]:INVALID;
///\brief Returns \c false if there are nodes
///Returns \c false if there are nodes
///to be processed in the queue (stack).
bool emptyQueue() const { return _stack_head<0; }
///Returns the number of the nodes to be processed.
///Returns the number of the nodes to be processed in the queue (stack).
int queueSize() const { return _stack_head+1; }
///Executes the algorithm.
///Executes the algorithm.
///This method runs the %DFS algorithm from the root node
///in order to compute the DFS path to each node.
/// The algorithm computes
///- the distance of each node from the root in the %DFS tree.
///\pre init() must be called and a root node should be
///added with addSource() before using this function.
///\note <tt>d.start()</tt> is just a shortcut of the following code.
/// while ( !d.emptyQueue() ) {
while ( !emptyQueue() ) processNextArc();
///Executes the algorithm until the given target node is reached.
///Executes the algorithm until the given target node is reached.
///This method runs the %DFS algorithm from the root node
///in order to compute the DFS path to \c dest.
///The algorithm computes
///- the %DFS path to \c dest,
///- the distance of \c dest from the root in the %DFS tree.
///\pre init() must be called and a root node should be
///added with addSource() before using this function.
while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest )
///Executes the algorithm until a condition is met.
///Executes the algorithm until a condition is met.
///This method runs the %DFS algorithm from the root node
///until an arc \c a with <tt>am[a]</tt> true is found.
///\param am A \c bool (or convertible) arc map. The algorithm
///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
///\return The reached arc \c a with <tt>am[a]</tt> true or
///\c INVALID if no such arc was found.
///\pre init() must be called and a root node should be
///added with addSource() before using this function.
///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
template<class ArcBoolMap>
Arc start(const ArcBoolMap &am)
while ( !emptyQueue() && !am[_stack[_stack_head]] )
return emptyQueue() ? INVALID : _stack[_stack_head];
///Runs the algorithm from the given node.
///This method runs the %DFS algorithm from node \c s
///in order to compute the DFS path to each node.
///The algorithm computes
///- the distance of each node from the root in the %DFS tree.
///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
///Finds the %DFS path between \c s and \c t.
///This method runs the %DFS algorithm from node \c s
///in order to compute the DFS path to \c t.
///\return The length of the <tt>s</tt>--<tt>t</tt> DFS path,
///if \c t is reachable form \c s, \c 0 otherwise.
///\note Apart from the return value, <tt>d.run(s,t)</tt> is
///just a shortcut of the following code.
return reached(t)?_stack_head+1:0;
///Runs the algorithm to visit all nodes in the digraph.
///This method runs the %DFS algorithm in order to compute the
///%DFS path to each node.
///The algorithm computes
///- the distance of each node from the root in the %DFS tree.
///\note <tt>d.run()</tt> is just a shortcut of the following code.
/// for (NodeIt n(digraph); n != INVALID; ++n) {
for (NodeIt it(*G); it != INVALID; ++it) {
///The result of the %DFS algorithm can be obtained using these
///Either \ref lemon::Dfs::run() "run()" or \ref lemon::Dfs::start()
///"start()" must be called before using them.
///The DFS path to a node.
///Returns the DFS path to a node.
///\warning \c t should be reachable from the root.
///\pre Either \ref run() or \ref start() must be called before
Path path(Node t) const { return Path(*G, *_pred, t); }
///The distance of a node from the root.
///Returns the distance of a node from the root.
///\warning If node \c v is not reachable from the root, then
///the return value of this function is undefined.
///\pre Either \ref run() or \ref start() must be called before
int dist(Node v) const { return (*_dist)[v]; }
///Returns the 'previous arc' of the %DFS tree for a node.
///This function returns the 'previous arc' of the %DFS tree for the
///node \c v, i.e. it returns the last arc of a %DFS path from the
///root to \c v. It is \c INVALID
///if \c v is not reachable from the root(s) or if \c v is a root.
///The %DFS tree used here is equal to the %DFS tree used in
///\pre Either \ref run() or \ref start() must be called before using
Arc predArc(Node v) const { return (*_pred)[v];}
///Returns the 'previous node' of the %DFS tree.
///This function returns the 'previous node' of the %DFS
///tree for the node \c v, i.e. it returns the last but one node
///from a %DFS path from the root to \c v. It is \c INVALID
///if \c v is not reachable from the root(s) or if \c v is a root.
///The %DFS tree used here is equal to the %DFS tree used in
///\pre Either \ref run() or \ref start() must be called before
Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
G->source((*_pred)[v]); }
///\brief Returns a const reference to the node map that stores the
///distances of the nodes.
///Returns a const reference to the node map that stores the
///distances of the nodes calculated by the algorithm.
///\pre Either \ref run() or \ref init()
///must be called before using this function.
const DistMap &distMap() const { return *_dist;}
///\brief Returns a const reference to the node map that stores the
///Returns a const reference to the node map that stores the predecessor
///arcs, which form the DFS tree.
///\pre Either \ref run() or \ref init()
///must be called before using this function.
const PredMap &predMap() const { return *_pred;}
///Checks if a node is reachable from the root(s).
///Returns \c true if \c v is reachable from the root(s).
///\pre Either \ref run() or \ref start()
///must be called before using this function.
bool reached(Node v) const { return (*_reached)[v]; }
///Default traits class of dfs() function.
///Default traits class of dfs() function.
///\tparam GR Digraph type.
struct DfsWizardDefaultTraits
///The type of the digraph the algorithm runs on.
///\brief The type of the map that stores the predecessor
///arcs of the %DFS paths.
///The type of the map that stores the predecessor
///arcs of the %DFS paths.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
///Instantiates a \ref PredMap.
///This function instantiates a \ref PredMap.
///\param g is the digraph, to which we would like to define the
///\todo The digraph alone may be insufficient to initialize
static PredMap *createPredMap(const Digraph &g)
///The type of the map that indicates which nodes are processed.
///The type of the map that indicates which nodes are processed.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
///By default it is a NullMap.
typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
///Instantiates a \ref ProcessedMap.
///This function instantiates a \ref ProcessedMap.
///\param g is the digraph, to which
///we would like to define the \ref ProcessedMap.
static ProcessedMap *createProcessedMap(const Digraph &g)
static ProcessedMap *createProcessedMap(const Digraph &)
return new ProcessedMap();
///The type of the map that indicates which nodes are reached.
///The type of the map that indicates which nodes are reached.
///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
typedef typename Digraph::template NodeMap<bool> ReachedMap;
///Instantiates a \ref ReachedMap.
///This function instantiates a \ref ReachedMap.
///\param g is the digraph, to which
///we would like to define the \ref ReachedMap.
static ReachedMap *createReachedMap(const Digraph &g)
return new ReachedMap(g);
///The type of the map that stores the distances of the nodes.
///The type of the map that stores the distances of the nodes.
///It must meet the \ref concepts::WriteMap "WriteMap" concept.
typedef typename Digraph::template NodeMap<int> DistMap;
///Instantiates a \ref DistMap.
///This function instantiates a \ref DistMap.
///\param g is the digraph, to which we would like to define
static DistMap *createDistMap(const Digraph &g)
///The type of the DFS paths.
///The type of the DFS paths.
///It must meet the \ref concepts::Path "Path" concept.
typedef lemon::Path<Digraph> Path;
/// Default traits class used by \ref DfsWizard
/// To make it easier to use Dfs algorithm
/// we have created a wizard class.
/// This \ref DfsWizard class needs default traits,
/// as well as the \ref Dfs class.
/// The \ref DfsWizardBase is a class to be the default traits of the
/// \ref DfsWizard class.
class DfsWizardBase : public DfsWizardDefaultTraits<GR>
typedef DfsWizardDefaultTraits<GR> Base;
//The type of the nodes in the digraph.
typedef typename Base::Digraph::Node Node;
//Pointer to the digraph the algorithm runs on.
//Pointer to the map of reached nodes.
//Pointer to the map of processed nodes.
//Pointer to the map of predecessors arcs.
//Pointer to the map of distances.
//Pointer to the DFS path to the target node.
//Pointer to the distance of the target node.
/// This constructor does not require parameters, therefore it initiates
/// all of the attributes to \c 0.
DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
_dist(0), _path(0), _di(0) {}
/// This constructor requires one parameter,
/// others are initiated to \c 0.
/// \param g The digraph the algorithm runs on.
DfsWizardBase(const GR &g) :
_g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
_reached(0), _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
/// Auxiliary class for the function-type interface of DFS algorithm.
/// This auxiliary class is created to implement the
/// \ref dfs() "function-type interface" of \ref Dfs algorithm.
/// It does not have own \ref run() method, it uses the functions
/// and features of the plain \ref Dfs.
/// This class should only be used through the \ref dfs() function,
/// which makes it easier to use the algorithm.
class DfsWizard : public TR
///The type of the digraph the algorithm runs on.
typedef typename TR::Digraph Digraph;
typedef typename Digraph::Node Node;
typedef typename Digraph::NodeIt NodeIt;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::OutArcIt OutArcIt;
///\brief The type of the map that stores the predecessor
///arcs of the DFS paths.
typedef typename TR::PredMap PredMap;
///\brief The type of the map that stores the distances of the nodes.
typedef typename TR::DistMap DistMap;
///\brief The type of the map that indicates which nodes are reached.
typedef typename TR::ReachedMap ReachedMap;
///\brief The type of the map that indicates which nodes are processed.
typedef typename TR::ProcessedMap ProcessedMap;
///The type of the DFS paths
typedef typename TR::Path Path;
/// Constructor that requires parameters.
/// Constructor that requires parameters.
/// These parameters will be the default values for the traits class.
/// \param g The digraph the algorithm runs on.
DfsWizard(const Digraph &g) :
DfsWizard(const TR &b) : TR(b) {}
///Runs DFS algorithm from the given source node.
///This method runs DFS algorithm from node \c s
///in order to compute the DFS path to each node.
Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
///Finds the DFS path between \c s and \c t.
///This method runs DFS algorithm from node \c s
///in order to compute the DFS path to node \c t
///(it stops searching when \c t is processed).
///\return \c true if \c t is reachable form \c s.
if (s==INVALID || t==INVALID) throw UninitializedParameter();
Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
*reinterpret_cast<Path*>(Base::_path) = alg.path(t);
*Base::_di = alg.dist(t);
///Runs DFS algorithm to visit all nodes in the digraph.
///This method runs DFS algorithm in order to compute
///the DFS path to each node.
struct SetPredMapBase : public Base {
static PredMap *createPredMap(const Digraph &) { return 0; };
SetPredMapBase(const TR &b) : TR(b) {}
///\brief \ref named-func-param "Named parameter"
///for setting \ref PredMap object.
///\ref named-func-param "Named parameter"
///for setting \ref PredMap object.
DfsWizard<SetPredMapBase<T> > predMap(const T &t)
Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
return DfsWizard<SetPredMapBase<T> >(*this);
struct SetReachedMapBase : public Base {
static ReachedMap *createReachedMap(const Digraph &) { return 0; };
SetReachedMapBase(const TR &b) : TR(b) {}
///\brief \ref named-func-param "Named parameter"
///for setting \ref ReachedMap object.
/// \ref named-func-param "Named parameter"
///for setting \ref ReachedMap object.
DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
return DfsWizard<SetReachedMapBase<T> >(*this);
struct SetDistMapBase : public Base {
static DistMap *createDistMap(const Digraph &) { return 0; };
SetDistMapBase(const TR &b) : TR(b) {}
///\brief \ref named-func-param "Named parameter"
///for setting \ref DistMap object.
/// \ref named-func-param "Named parameter"
///for setting \ref DistMap object.
DfsWizard<SetDistMapBase<T> > distMap(const T &t)
Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
return DfsWizard<SetDistMapBase<T> >(*this);
struct SetProcessedMapBase : public Base {
static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
SetProcessedMapBase(const TR &b) : TR(b) {}
///\brief \ref named-func-param "Named parameter"
///for setting \ref ProcessedMap object.
/// \ref named-func-param "Named parameter"
///for setting \ref ProcessedMap object.
DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
return DfsWizard<SetProcessedMapBase<T> >(*this);
struct SetPathBase : public Base {
SetPathBase(const TR &b) : TR(b) {}
///\brief \ref named-func-param "Named parameter"
///for getting the DFS path to the target node.
///\ref named-func-param "Named parameter"
///for getting the DFS path to the target node.
DfsWizard<SetPathBase<T> > path(const T &t)
Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
return DfsWizard<SetPathBase<T> >(*this);
///\brief \ref named-func-param "Named parameter"
///for getting the distance of the target node.
///\ref named-func-param "Named parameter"
///for getting the distance of the target node.
DfsWizard dist(const int &d)
Base::_di=const_cast<int*>(&d);
///Function-type interface for DFS algorithm.
///Function-type interface for DFS algorithm.
///This function also has several \ref named-func-param "named parameters",
///they are declared as the members of class \ref DfsWizard.
///The following examples show how to use these parameters.
/// // Compute the DFS tree
/// dfs(g).predMap(preds).distMap(dists).run(s);
/// // Compute the DFS path from s to t
/// bool reached = dfs(g).path(p).dist(d).run(s,t);
///\warning Don't forget to put the \ref DfsWizard::run() "run()"
///to the end of the parameter list.
DfsWizard<DfsWizardBase<GR> >
return DfsWizard<DfsWizardBase<GR> >(digraph);
/// \brief Visitor class for DFS.
/// This class defines the interface of the DfsVisit events, and
/// it could be the base of a real visitor class.
template <typename _Digraph>
typedef _Digraph Digraph;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::Node Node;
/// \brief Called for the source node of the DFS.
/// This function is called for the source node of the DFS.
void start(const Node& node) {}
/// \brief Called when the source node is leaved.
/// This function is called when the source node is leaved.
void stop(const Node& node) {}
/// \brief Called when a node is reached first time.
/// This function is called when a node is reached first time.
void reach(const Node& node) {}
/// \brief Called when an arc reaches a new node.
/// This function is called when the DFS finds an arc whose target node
void discover(const Arc& arc) {}
/// \brief Called when an arc is examined but its target node is
/// This function is called when an arc is examined but its target node is
void examine(const Arc& arc) {}
/// \brief Called when the DFS steps back from a node.
/// This function is called when the DFS steps back from a node.
void leave(const Node& node) {}
/// \brief Called when the DFS steps back on an arc.
/// This function is called when the DFS steps back on an arc.
void backtrack(const Arc& arc) {}
template <typename _Digraph>
typedef _Digraph Digraph;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::Node Node;
void start(const Node&) {}
void stop(const Node&) {}
void reach(const Node&) {}
void discover(const Arc&) {}
void examine(const Arc&) {}
void leave(const Node&) {}
void backtrack(const Arc&) {}
template <typename _Visitor>
/// \brief Default traits class of DfsVisit class.
/// Default traits class of DfsVisit class.
/// \tparam _Digraph The type of the digraph the algorithm runs on.
struct DfsVisitDefaultTraits {
/// \brief The type of the digraph the algorithm runs on.
typedef _Digraph Digraph;
/// \brief The type of the map that indicates which nodes are reached.
/// The type of the map that indicates which nodes are reached.
/// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
typedef typename Digraph::template NodeMap<bool> ReachedMap;
/// \brief Instantiates a \ref ReachedMap.
/// This function instantiates a \ref ReachedMap.
/// \param digraph is the digraph, to which
/// we would like to define the \ref ReachedMap.
static ReachedMap *createReachedMap(const Digraph &digraph) {
return new ReachedMap(digraph);
/// \brief %DFS algorithm class with visitor interface.
/// This class provides an efficient implementation of the %DFS algorithm
/// with visitor interface.
/// The %DfsVisit class provides an alternative interface to the Dfs
/// class. It works with callback mechanism, the DfsVisit object calls
/// the member functions of the \c Visitor class on every DFS event.
/// This interface of the DFS algorithm should be used in special cases
/// when extra actions have to be performed in connection with certain
/// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
/// \tparam _Digraph The type of the digraph the algorithm runs on.
/// \ref ListDigraph. The value of _Digraph is not used directly by
/// \ref DfsVisit, it is only passed to \ref DfsVisitDefaultTraits.
/// \tparam _Visitor The Visitor type that is used by the algorithm.
/// \ref DfsVisitor "DfsVisitor<_Digraph>" is an empty visitor, which
/// does not observe the DFS events. If you want to observe the DFS
/// events, you should implement your own visitor class.
/// \tparam _Traits Traits class to set various data types used by the
/// algorithm. The default traits class is
/// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<_Digraph>".
/// See \ref DfsVisitDefaultTraits for the documentation of
/// a DFS visit traits class.
template <typename _Digraph, typename _Visitor, typename _Traits>
template <typename _Digraph = ListDigraph,
typename _Visitor = DfsVisitor<_Digraph>,
typename _Traits = DfsDefaultTraits<_Digraph> >
/// \brief \ref Exception for uninitialized parameters.
/// This error represents problems in the initialization
/// of the parameters of the algorithm.
class UninitializedParameter : public lemon::UninitializedParameter {
virtual const char* what() const throw()
return "lemon::DfsVisit::UninitializedParameter";
///The type of the digraph the algorithm runs on.
typedef typename Traits::Digraph Digraph;
///The visitor type used by the algorithm.
typedef _Visitor Visitor;
///The type of the map that indicates which nodes are reached.
typedef typename Traits::ReachedMap ReachedMap;
typedef typename Digraph::Node Node;
typedef typename Digraph::NodeIt NodeIt;
typedef typename Digraph::Arc Arc;
typedef typename Digraph::OutArcIt OutArcIt;
//Pointer to the underlying digraph.
//Pointer to the visitor object.
//Pointer to the map of reached status of the nodes.
//Indicates if _reached is locally allocated (true) or not.
std::vector<typename Digraph::Arc> _stack;
///Creates the maps if necessary.
///\todo Better memory allocation (instead of new).
_reached = Traits::createReachedMap(*_digraph);
/// \name Named template parameters
struct SetReachedMapTraits : public Traits {
static ReachedMap *createReachedMap(const Digraph &digraph) {
throw UninitializedParameter();
/// \brief \ref named-templ-param "Named parameter" for setting
/// \ref named-templ-param "Named parameter" for setting ReachedMap type.
struct SetReachedMap : public DfsVisit< Digraph, Visitor,
SetReachedMapTraits<T> > {
typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
/// \param digraph The digraph the algorithm runs on.
/// \param visitor The visitor object of the algorithm.
DfsVisit(const Digraph& digraph, Visitor& visitor)
: _digraph(&digraph), _visitor(&visitor),
_reached(0), local_reached(false) {}
if(local_reached) delete _reached;
/// \brief Sets the map that indicates which nodes are reached.
/// Sets the map that indicates which nodes are reached.
/// If you don't use this function before calling \ref run(),
/// it will allocate one. The destructor deallocates this
/// automatically allocated map, of course.
/// \return <tt> (*this) </tt>
DfsVisit &reachedMap(ReachedMap &m) {
/// \name Execution control
/// The simplest way to execute the algorithm is to use
/// one of the member functions called \ref lemon::DfsVisit::run()
/// If you need more control on the execution, first you must call
/// \ref lemon::DfsVisit::init() "init()", then you can add several
/// source nodes with \ref lemon::DfsVisit::addSource() "addSource()".
/// Finally \ref lemon::DfsVisit::start() "start()" will perform the
/// actual path computation.
/// \brief Initializes the internal data structures.
/// Initializes the internal data structures.
_stack.resize(countNodes(*_digraph));
for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
///Adds a new source node.
///Adds a new source node to the set of nodes to be processed.
///\pre The stack must be empty. (Otherwise the algorithm gives
///\warning Distances will be wrong (or at least strange) in case of
LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
_digraph->firstOut(e, s);
_stack[++_stack_head] = e;
/// \brief Processes the next arc.
/// Processes the next arc.
/// \return The processed arc.
/// \pre The stack must not be empty.
Arc e = _stack[_stack_head];
Node m = _digraph->target(e);
_digraph->firstOut(_stack[++_stack_head], m);
_digraph->nextOut(_stack[_stack_head]);
while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
_visitor->backtrack(_stack[_stack_head]);
m = _digraph->source(_stack[_stack_head]);
_digraph->nextOut(_stack[_stack_head]);
/// \brief Next arc to be processed.
/// Next arc to be processed.
/// \return The next arc to be processed or INVALID if the stack is
return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
/// \brief Returns \c false if there are nodes
/// Returns \c false if there are nodes
/// to be processed in the queue (stack).
bool emptyQueue() const { return _stack_head < 0; }
/// \brief Returns the number of the nodes to be processed.
/// Returns the number of the nodes to be processed in the queue (stack).
int queueSize() const { return _stack_head + 1; }
/// \brief Executes the algorithm.
/// Executes the algorithm.
/// This method runs the %DFS algorithm from the root node
/// in order to compute the %DFS path to each node.
/// The algorithm computes
/// - the distance of each node from the root in the %DFS tree.
/// \pre init() must be called and a root node should be
/// added with addSource() before using this function.
/// \note <tt>d.start()</tt> is just a shortcut of the following code.
/// while ( !d.emptyQueue() ) {
while ( !emptyQueue() ) processNextArc();
/// \brief Executes the algorithm until the given target node is reached.
/// Executes the algorithm until the given target node is reached.
/// This method runs the %DFS algorithm from the root node
/// in order to compute the DFS path to \c dest.
/// The algorithm computes
/// - the %DFS path to \c dest,
/// - the distance of \c dest from the root in the %DFS tree.
/// \pre init() must be called and a root node should be added
/// with addSource() before using this function.
while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != dest )
/// \brief Executes the algorithm until a condition is met.
/// Executes the algorithm until a condition is met.
/// This method runs the %DFS algorithm from the root node
/// until an arc \c a with <tt>am[a]</tt> true is found.
/// \param am A \c bool (or convertible) arc map. The algorithm
/// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
/// \return The reached arc \c a with <tt>am[a]</tt> true or
/// \c INVALID if no such arc was found.
/// \pre init() must be called and a root node should be added
/// with addSource() before using this function.
/// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
Arc start(const AM &am) {
while ( !emptyQueue() && !am[_stack[_stack_head]] )
return emptyQueue() ? INVALID : _stack[_stack_head];
/// \brief Runs the algorithm from the given node.
/// This method runs the %DFS algorithm from node \c s.
/// in order to compute the DFS path to each node.
/// The algorithm computes
/// - the distance of each node from the root in the %DFS tree.
/// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
/// \brief Finds the %DFS path between \c s and \c t.
/// This method runs the %DFS algorithm from node \c s
/// in order to compute the DFS path to \c t.
/// \return The length of the <tt>s</tt>--<tt>t</tt> DFS path,
/// if \c t is reachable form \c s, \c 0 otherwise.
/// \note Apart from the return value, <tt>d.run(s,t)</tt> is
/// just a shortcut of the following code.
return reached(t)?_stack_head+1:0;
/// \brief Runs the algorithm to visit all nodes in the digraph.
/// This method runs the %DFS algorithm in order to
/// compute the %DFS path to each node.
/// The algorithm computes
/// - the distance of each node from the root in the %DFS tree.
/// \note <tt>d.run()</tt> is just a shortcut of the following code.
/// for (NodeIt n(digraph); n != INVALID; ++n) {
for (NodeIt it(*_digraph); it != INVALID; ++it) {
/// \name Query Functions
/// The result of the %DFS algorithm can be obtained using these
/// Either \ref lemon::DfsVisit::run() "run()" or
/// \ref lemon::DfsVisit::start() "start()" must be called before
/// \brief Checks if a node is reachable from the root(s).
/// Returns \c true if \c v is reachable from the root(s).
/// \pre Either \ref run() or \ref start()
/// must be called before using this function.
bool reached(Node v) { return (*_reached)[v]; }
} //END OF NAMESPACE LEMON