lemon/dfs.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Mar 2009 00:18:25 +0100
changeset 604 8c3112a66878
parent 440 88ed40ad0d4f
child 584 33c6b6e755cd
permissions -rw-r--r--
Use XTI implementation instead of ATI in NetworkSimplex (#234)

XTI (eXtended Threaded Index) is an imporved version of the widely
known ATI (Augmented Threaded Index) method for storing and updating
the spanning tree structure in Network Simplex algorithms.

In the ATI data structure three indices are stored for each node:
predecessor, thread and depth. In the XTI data structure depth is
replaced by the number of successors and the last successor
(according to the thread index).
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@100
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@100
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
alpar@100
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@100
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@100
     8
 *
alpar@100
     9
 * Permission to use, modify and distribute this software is granted
alpar@100
    10
 * provided that this copyright notice appears in all copies. For
alpar@100
    11
 * precise terms see the accompanying LICENSE file.
alpar@100
    12
 *
alpar@100
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@100
    14
 * express or implied, and with no claim as to its suitability for any
alpar@100
    15
 * purpose.
alpar@100
    16
 *
alpar@100
    17
 */
alpar@100
    18
alpar@100
    19
#ifndef LEMON_DFS_H
alpar@100
    20
#define LEMON_DFS_H
alpar@100
    21
alpar@100
    22
///\ingroup search
alpar@100
    23
///\file
kpeter@244
    24
///\brief DFS algorithm.
alpar@100
    25
alpar@100
    26
#include <lemon/list_graph.h>
alpar@100
    27
#include <lemon/bits/path_dump.h>
deba@220
    28
#include <lemon/core.h>
alpar@100
    29
#include <lemon/error.h>
alpar@100
    30
#include <lemon/maps.h>
kpeter@278
    31
#include <lemon/path.h>
alpar@100
    32
alpar@100
    33
namespace lemon {
alpar@100
    34
alpar@100
    35
  ///Default traits class of Dfs class.
alpar@100
    36
alpar@100
    37
  ///Default traits class of Dfs class.
kpeter@157
    38
  ///\tparam GR Digraph type.
alpar@100
    39
  template<class GR>
alpar@100
    40
  struct DfsDefaultTraits
alpar@100
    41
  {
kpeter@244
    42
    ///The type of the digraph the algorithm runs on.
alpar@100
    43
    typedef GR Digraph;
kpeter@244
    44
kpeter@244
    45
    ///\brief The type of the map that stores the predecessor
alpar@100
    46
    ///arcs of the %DFS paths.
alpar@209
    47
    ///
kpeter@244
    48
    ///The type of the map that stores the predecessor
alpar@100
    49
    ///arcs of the %DFS paths.
alpar@100
    50
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
kpeter@244
    51
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
kpeter@492
    52
    ///Instantiates a \c PredMap.
alpar@209
    53
kpeter@492
    54
    ///This function instantiates a \ref PredMap.
kpeter@244
    55
    ///\param g is the digraph, to which we would like to define the
kpeter@492
    56
    ///\ref PredMap.
kpeter@244
    57
    static PredMap *createPredMap(const Digraph &g)
alpar@100
    58
    {
kpeter@244
    59
      return new PredMap(g);
alpar@100
    60
    }
alpar@100
    61
alpar@100
    62
    ///The type of the map that indicates which nodes are processed.
alpar@209
    63
alpar@100
    64
    ///The type of the map that indicates which nodes are processed.
alpar@100
    65
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
alpar@100
    66
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
kpeter@492
    67
    ///Instantiates a \c ProcessedMap.
alpar@209
    68
kpeter@492
    69
    ///This function instantiates a \ref ProcessedMap.
alpar@100
    70
    ///\param g is the digraph, to which
kpeter@492
    71
    ///we would like to define the \ref ProcessedMap.
alpar@100
    72
#ifdef DOXYGEN
kpeter@244
    73
    static ProcessedMap *createProcessedMap(const Digraph &g)
alpar@100
    74
#else
kpeter@244
    75
    static ProcessedMap *createProcessedMap(const Digraph &)
alpar@100
    76
#endif
alpar@100
    77
    {
alpar@100
    78
      return new ProcessedMap();
alpar@100
    79
    }
kpeter@244
    80
alpar@100
    81
    ///The type of the map that indicates which nodes are reached.
alpar@209
    82
alpar@100
    83
    ///The type of the map that indicates which nodes are reached.
kpeter@244
    84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
alpar@100
    85
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
kpeter@492
    86
    ///Instantiates a \c ReachedMap.
alpar@209
    87
kpeter@492
    88
    ///This function instantiates a \ref ReachedMap.
kpeter@244
    89
    ///\param g is the digraph, to which
kpeter@492
    90
    ///we would like to define the \ref ReachedMap.
kpeter@244
    91
    static ReachedMap *createReachedMap(const Digraph &g)
alpar@100
    92
    {
kpeter@244
    93
      return new ReachedMap(g);
alpar@100
    94
    }
alpar@209
    95
kpeter@244
    96
    ///The type of the map that stores the distances of the nodes.
kpeter@244
    97
kpeter@244
    98
    ///The type of the map that stores the distances of the nodes.
alpar@100
    99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
alpar@100
   100
    typedef typename Digraph::template NodeMap<int> DistMap;
kpeter@492
   101
    ///Instantiates a \c DistMap.
alpar@209
   102
kpeter@492
   103
    ///This function instantiates a \ref DistMap.
kpeter@244
   104
    ///\param g is the digraph, to which we would like to define the
kpeter@492
   105
    ///\ref DistMap.
kpeter@244
   106
    static DistMap *createDistMap(const Digraph &g)
alpar@100
   107
    {
kpeter@244
   108
      return new DistMap(g);
alpar@100
   109
    }
alpar@100
   110
  };
alpar@209
   111
alpar@100
   112
  ///%DFS algorithm class.
alpar@209
   113
alpar@100
   114
  ///\ingroup search
alpar@100
   115
  ///This class provides an efficient implementation of the %DFS algorithm.
alpar@100
   116
  ///
kpeter@278
   117
  ///There is also a \ref dfs() "function-type interface" for the DFS
kpeter@244
   118
  ///algorithm, which is convenient in the simplier cases and it can be
kpeter@244
   119
  ///used easier.
kpeter@244
   120
  ///
kpeter@244
   121
  ///\tparam GR The type of the digraph the algorithm runs on.
kpeter@405
   122
  ///The default type is \ref ListDigraph.
alpar@100
   123
#ifdef DOXYGEN
alpar@100
   124
  template <typename GR,
alpar@209
   125
            typename TR>
alpar@100
   126
#else
alpar@100
   127
  template <typename GR=ListDigraph,
alpar@209
   128
            typename TR=DfsDefaultTraits<GR> >
alpar@100
   129
#endif
alpar@100
   130
  class Dfs {
alpar@100
   131
  public:
alpar@100
   132
kpeter@244
   133
    ///The type of the digraph the algorithm runs on.
kpeter@244
   134
    typedef typename TR::Digraph Digraph;
kpeter@244
   135
kpeter@244
   136
    ///\brief The type of the map that stores the predecessor arcs of the
kpeter@244
   137
    ///DFS paths.
kpeter@244
   138
    typedef typename TR::PredMap PredMap;
kpeter@244
   139
    ///The type of the map that stores the distances of the nodes.
kpeter@244
   140
    typedef typename TR::DistMap DistMap;
kpeter@244
   141
    ///The type of the map that indicates which nodes are reached.
kpeter@244
   142
    typedef typename TR::ReachedMap ReachedMap;
kpeter@244
   143
    ///The type of the map that indicates which nodes are processed.
kpeter@244
   144
    typedef typename TR::ProcessedMap ProcessedMap;
kpeter@244
   145
    ///The type of the paths.
kpeter@244
   146
    typedef PredMapPath<Digraph, PredMap> Path;
kpeter@244
   147
kpeter@405
   148
    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
alpar@100
   149
    typedef TR Traits;
kpeter@244
   150
kpeter@244
   151
  private:
kpeter@244
   152
alpar@100
   153
    typedef typename Digraph::Node Node;
alpar@100
   154
    typedef typename Digraph::NodeIt NodeIt;
alpar@100
   155
    typedef typename Digraph::Arc Arc;
alpar@100
   156
    typedef typename Digraph::OutArcIt OutArcIt;
alpar@209
   157
kpeter@244
   158
    //Pointer to the underlying digraph.
alpar@100
   159
    const Digraph *G;
kpeter@244
   160
    //Pointer to the map of predecessor arcs.
alpar@100
   161
    PredMap *_pred;
kpeter@244
   162
    //Indicates if _pred is locally allocated (true) or not.
alpar@100
   163
    bool local_pred;
kpeter@244
   164
    //Pointer to the map of distances.
alpar@100
   165
    DistMap *_dist;
kpeter@244
   166
    //Indicates if _dist is locally allocated (true) or not.
alpar@100
   167
    bool local_dist;
kpeter@244
   168
    //Pointer to the map of reached status of the nodes.
alpar@100
   169
    ReachedMap *_reached;
kpeter@244
   170
    //Indicates if _reached is locally allocated (true) or not.
alpar@100
   171
    bool local_reached;
kpeter@244
   172
    //Pointer to the map of processed status of the nodes.
alpar@100
   173
    ProcessedMap *_processed;
kpeter@244
   174
    //Indicates if _processed is locally allocated (true) or not.
alpar@100
   175
    bool local_processed;
alpar@100
   176
alpar@100
   177
    std::vector<typename Digraph::OutArcIt> _stack;
alpar@100
   178
    int _stack_head;
alpar@100
   179
alpar@280
   180
    //Creates the maps if necessary.
alpar@209
   181
    void create_maps()
alpar@100
   182
    {
alpar@100
   183
      if(!_pred) {
alpar@209
   184
        local_pred = true;
alpar@209
   185
        _pred = Traits::createPredMap(*G);
alpar@100
   186
      }
alpar@100
   187
      if(!_dist) {
alpar@209
   188
        local_dist = true;
alpar@209
   189
        _dist = Traits::createDistMap(*G);
alpar@100
   190
      }
alpar@100
   191
      if(!_reached) {
alpar@209
   192
        local_reached = true;
alpar@209
   193
        _reached = Traits::createReachedMap(*G);
alpar@100
   194
      }
alpar@100
   195
      if(!_processed) {
alpar@209
   196
        local_processed = true;
alpar@209
   197
        _processed = Traits::createProcessedMap(*G);
alpar@100
   198
      }
alpar@100
   199
    }
alpar@100
   200
alpar@100
   201
  protected:
alpar@100
   202
alpar@100
   203
    Dfs() {}
alpar@209
   204
alpar@100
   205
  public:
alpar@100
   206
alpar@100
   207
    typedef Dfs Create;
alpar@100
   208
alpar@100
   209
    ///\name Named template parameters
alpar@100
   210
alpar@100
   211
    ///@{
alpar@100
   212
alpar@100
   213
    template <class T>
kpeter@257
   214
    struct SetPredMapTraits : public Traits {
alpar@100
   215
      typedef T PredMap;
kpeter@244
   216
      static PredMap *createPredMap(const Digraph &)
alpar@100
   217
      {
deba@290
   218
        LEMON_ASSERT(false, "PredMap is not initialized");
deba@290
   219
        return 0; // ignore warnings
alpar@100
   220
      }
alpar@100
   221
    };
alpar@100
   222
    ///\brief \ref named-templ-param "Named parameter" for setting
kpeter@492
   223
    ///\c PredMap type.
alpar@100
   224
    ///
kpeter@244
   225
    ///\ref named-templ-param "Named parameter" for setting
kpeter@492
   226
    ///\c PredMap type.
kpeter@405
   227
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
alpar@100
   228
    template <class T>
kpeter@257
   229
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
kpeter@257
   230
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
alpar@100
   231
    };
alpar@209
   232
alpar@100
   233
    template <class T>
kpeter@257
   234
    struct SetDistMapTraits : public Traits {
alpar@100
   235
      typedef T DistMap;
alpar@209
   236
      static DistMap *createDistMap(const Digraph &)
alpar@100
   237
      {
deba@290
   238
        LEMON_ASSERT(false, "DistMap is not initialized");
deba@290
   239
        return 0; // ignore warnings
alpar@100
   240
      }
alpar@100
   241
    };
alpar@100
   242
    ///\brief \ref named-templ-param "Named parameter" for setting
kpeter@492
   243
    ///\c DistMap type.
alpar@100
   244
    ///
kpeter@244
   245
    ///\ref named-templ-param "Named parameter" for setting
kpeter@492
   246
    ///\c DistMap type.
kpeter@405
   247
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
alpar@100
   248
    template <class T>
kpeter@257
   249
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
kpeter@257
   250
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
alpar@100
   251
    };
alpar@209
   252
alpar@100
   253
    template <class T>
kpeter@257
   254
    struct SetReachedMapTraits : public Traits {
alpar@100
   255
      typedef T ReachedMap;
alpar@209
   256
      static ReachedMap *createReachedMap(const Digraph &)
alpar@100
   257
      {
deba@290
   258
        LEMON_ASSERT(false, "ReachedMap is not initialized");
deba@290
   259
        return 0; // ignore warnings
alpar@100
   260
      }
alpar@100
   261
    };
alpar@100
   262
    ///\brief \ref named-templ-param "Named parameter" for setting
kpeter@492
   263
    ///\c ReachedMap type.
alpar@100
   264
    ///
kpeter@244
   265
    ///\ref named-templ-param "Named parameter" for setting
kpeter@492
   266
    ///\c ReachedMap type.
kpeter@405
   267
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
alpar@100
   268
    template <class T>
kpeter@257
   269
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
kpeter@257
   270
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
alpar@100
   271
    };
alpar@100
   272
alpar@100
   273
    template <class T>
kpeter@257
   274
    struct SetProcessedMapTraits : public Traits {
alpar@100
   275
      typedef T ProcessedMap;
alpar@209
   276
      static ProcessedMap *createProcessedMap(const Digraph &)
alpar@100
   277
      {
deba@290
   278
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
deba@290
   279
        return 0; // ignore warnings
alpar@100
   280
      }
alpar@100
   281
    };
alpar@100
   282
    ///\brief \ref named-templ-param "Named parameter" for setting
kpeter@492
   283
    ///\c ProcessedMap type.
alpar@100
   284
    ///
kpeter@244
   285
    ///\ref named-templ-param "Named parameter" for setting
kpeter@492
   286
    ///\c ProcessedMap type.
kpeter@405
   287
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
alpar@100
   288
    template <class T>
kpeter@257
   289
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
kpeter@257
   290
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
alpar@100
   291
    };
alpar@209
   292
kpeter@257
   293
    struct SetStandardProcessedMapTraits : public Traits {
alpar@100
   294
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
kpeter@244
   295
      static ProcessedMap *createProcessedMap(const Digraph &g)
alpar@100
   296
      {
kpeter@244
   297
        return new ProcessedMap(g);
alpar@100
   298
      }
alpar@100
   299
    };
kpeter@244
   300
    ///\brief \ref named-templ-param "Named parameter" for setting
kpeter@492
   301
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
alpar@100
   302
    ///
kpeter@244
   303
    ///\ref named-templ-param "Named parameter" for setting
kpeter@492
   304
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
kpeter@244
   305
    ///If you don't set it explicitly, it will be automatically allocated.
kpeter@257
   306
    struct SetStandardProcessedMap :
kpeter@257
   307
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
kpeter@257
   308
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
alpar@100
   309
    };
alpar@209
   310
alpar@100
   311
    ///@}
alpar@100
   312
alpar@209
   313
  public:
alpar@209
   314
alpar@100
   315
    ///Constructor.
alpar@209
   316
kpeter@244
   317
    ///Constructor.
kpeter@244
   318
    ///\param g The digraph the algorithm runs on.
kpeter@244
   319
    Dfs(const Digraph &g) :
kpeter@244
   320
      G(&g),
alpar@100
   321
      _pred(NULL), local_pred(false),
alpar@100
   322
      _dist(NULL), local_dist(false),
alpar@100
   323
      _reached(NULL), local_reached(false),
alpar@100
   324
      _processed(NULL), local_processed(false)
alpar@100
   325
    { }
alpar@209
   326
alpar@100
   327
    ///Destructor.
alpar@209
   328
    ~Dfs()
alpar@100
   329
    {
alpar@100
   330
      if(local_pred) delete _pred;
alpar@100
   331
      if(local_dist) delete _dist;
alpar@100
   332
      if(local_reached) delete _reached;
alpar@100
   333
      if(local_processed) delete _processed;
alpar@100
   334
    }
alpar@100
   335
kpeter@244
   336
    ///Sets the map that stores the predecessor arcs.
alpar@100
   337
kpeter@244
   338
    ///Sets the map that stores the predecessor arcs.
kpeter@405
   339
    ///If you don't use this function before calling \ref run(Node) "run()"
kpeter@405
   340
    ///or \ref init(), an instance will be allocated automatically.
kpeter@405
   341
    ///The destructor deallocates this automatically allocated map,
kpeter@405
   342
    ///of course.
alpar@100
   343
    ///\return <tt> (*this) </tt>
alpar@209
   344
    Dfs &predMap(PredMap &m)
alpar@100
   345
    {
alpar@100
   346
      if(local_pred) {
alpar@209
   347
        delete _pred;
alpar@209
   348
        local_pred=false;
alpar@100
   349
      }
alpar@100
   350
      _pred = &m;
alpar@100
   351
      return *this;
alpar@100
   352
    }
alpar@100
   353
kpeter@244
   354
    ///Sets the map that indicates which nodes are reached.
alpar@100
   355
kpeter@244
   356
    ///Sets the map that indicates which nodes are reached.
kpeter@405
   357
    ///If you don't use this function before calling \ref run(Node) "run()"
kpeter@405
   358
    ///or \ref init(), an instance will be allocated automatically.
kpeter@405
   359
    ///The destructor deallocates this automatically allocated map,
kpeter@405
   360
    ///of course.
kpeter@244
   361
    ///\return <tt> (*this) </tt>
kpeter@244
   362
    Dfs &reachedMap(ReachedMap &m)
kpeter@244
   363
    {
kpeter@244
   364
      if(local_reached) {
kpeter@244
   365
        delete _reached;
kpeter@244
   366
        local_reached=false;
kpeter@244
   367
      }
kpeter@244
   368
      _reached = &m;
kpeter@244
   369
      return *this;
kpeter@244
   370
    }
kpeter@244
   371
kpeter@244
   372
    ///Sets the map that indicates which nodes are processed.
kpeter@244
   373
kpeter@244
   374
    ///Sets the map that indicates which nodes are processed.
kpeter@405
   375
    ///If you don't use this function before calling \ref run(Node) "run()"
kpeter@405
   376
    ///or \ref init(), an instance will be allocated automatically.
kpeter@405
   377
    ///The destructor deallocates this automatically allocated map,
kpeter@405
   378
    ///of course.
kpeter@244
   379
    ///\return <tt> (*this) </tt>
kpeter@244
   380
    Dfs &processedMap(ProcessedMap &m)
kpeter@244
   381
    {
kpeter@244
   382
      if(local_processed) {
kpeter@244
   383
        delete _processed;
kpeter@244
   384
        local_processed=false;
kpeter@244
   385
      }
kpeter@244
   386
      _processed = &m;
kpeter@244
   387
      return *this;
kpeter@244
   388
    }
kpeter@244
   389
kpeter@244
   390
    ///Sets the map that stores the distances of the nodes.
kpeter@244
   391
kpeter@244
   392
    ///Sets the map that stores the distances of the nodes calculated by
kpeter@244
   393
    ///the algorithm.
kpeter@405
   394
    ///If you don't use this function before calling \ref run(Node) "run()"
kpeter@405
   395
    ///or \ref init(), an instance will be allocated automatically.
kpeter@405
   396
    ///The destructor deallocates this automatically allocated map,
kpeter@405
   397
    ///of course.
alpar@100
   398
    ///\return <tt> (*this) </tt>
alpar@209
   399
    Dfs &distMap(DistMap &m)
alpar@100
   400
    {
alpar@100
   401
      if(local_dist) {
alpar@209
   402
        delete _dist;
alpar@209
   403
        local_dist=false;
alpar@100
   404
      }
alpar@100
   405
      _dist = &m;
alpar@100
   406
      return *this;
alpar@100
   407
    }
alpar@100
   408
kpeter@244
   409
  public:
alpar@100
   410
kpeter@405
   411
    ///\name Execution Control
kpeter@405
   412
    ///The simplest way to execute the DFS algorithm is to use one of the
kpeter@405
   413
    ///member functions called \ref run(Node) "run()".\n
kpeter@405
   414
    ///If you need more control on the execution, first you have to call
kpeter@405
   415
    ///\ref init(), then you can add a source node with \ref addSource()
kpeter@405
   416
    ///and perform the actual computation with \ref start().
kpeter@405
   417
    ///This procedure can be repeated if there are nodes that have not
kpeter@405
   418
    ///been reached.
alpar@100
   419
alpar@100
   420
    ///@{
alpar@100
   421
kpeter@405
   422
    ///\brief Initializes the internal data structures.
kpeter@405
   423
    ///
alpar@100
   424
    ///Initializes the internal data structures.
alpar@100
   425
    void init()
alpar@100
   426
    {
alpar@100
   427
      create_maps();
alpar@100
   428
      _stack.resize(countNodes(*G));
alpar@100
   429
      _stack_head=-1;
alpar@100
   430
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
alpar@209
   431
        _pred->set(u,INVALID);
alpar@209
   432
        _reached->set(u,false);
alpar@209
   433
        _processed->set(u,false);
alpar@100
   434
      }
alpar@100
   435
    }
alpar@209
   436
alpar@100
   437
    ///Adds a new source node.
alpar@100
   438
alpar@100
   439
    ///Adds a new source node to the set of nodes to be processed.
alpar@100
   440
    ///
kpeter@405
   441
    ///\pre The stack must be empty. Otherwise the algorithm gives
kpeter@405
   442
    ///wrong results. (One of the outgoing arcs of all the source nodes
kpeter@405
   443
    ///except for the last one will not be visited and distances will
kpeter@405
   444
    ///also be wrong.)
alpar@100
   445
    void addSource(Node s)
alpar@100
   446
    {
kpeter@244
   447
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
alpar@100
   448
      if(!(*_reached)[s])
alpar@209
   449
        {
alpar@209
   450
          _reached->set(s,true);
alpar@209
   451
          _pred->set(s,INVALID);
alpar@209
   452
          OutArcIt e(*G,s);
alpar@209
   453
          if(e!=INVALID) {
alpar@209
   454
            _stack[++_stack_head]=e;
alpar@209
   455
            _dist->set(s,_stack_head);
alpar@209
   456
          }
alpar@209
   457
          else {
alpar@209
   458
            _processed->set(s,true);
alpar@209
   459
            _dist->set(s,0);
alpar@209
   460
          }
alpar@209
   461
        }
alpar@100
   462
    }
alpar@209
   463
alpar@100
   464
    ///Processes the next arc.
alpar@100
   465
alpar@100
   466
    ///Processes the next arc.
alpar@100
   467
    ///
alpar@100
   468
    ///\return The processed arc.
alpar@100
   469
    ///
kpeter@244
   470
    ///\pre The stack must not be empty.
alpar@100
   471
    Arc processNextArc()
alpar@209
   472
    {
alpar@100
   473
      Node m;
alpar@100
   474
      Arc e=_stack[_stack_head];
alpar@100
   475
      if(!(*_reached)[m=G->target(e)]) {
alpar@209
   476
        _pred->set(m,e);
alpar@209
   477
        _reached->set(m,true);
alpar@209
   478
        ++_stack_head;
alpar@209
   479
        _stack[_stack_head] = OutArcIt(*G, m);
alpar@209
   480
        _dist->set(m,_stack_head);
alpar@100
   481
      }
alpar@100
   482
      else {
alpar@209
   483
        m=G->source(e);
alpar@209
   484
        ++_stack[_stack_head];
alpar@100
   485
      }
alpar@100
   486
      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
alpar@209
   487
        _processed->set(m,true);
alpar@209
   488
        --_stack_head;
alpar@209
   489
        if(_stack_head>=0) {
alpar@209
   490
          m=G->source(_stack[_stack_head]);
alpar@209
   491
          ++_stack[_stack_head];
alpar@209
   492
        }
alpar@100
   493
      }
alpar@100
   494
      return e;
alpar@100
   495
    }
kpeter@244
   496
alpar@100
   497
    ///Next arc to be processed.
alpar@100
   498
alpar@100
   499
    ///Next arc to be processed.
alpar@100
   500
    ///
kpeter@244
   501
    ///\return The next arc to be processed or \c INVALID if the stack
kpeter@244
   502
    ///is empty.
kpeter@244
   503
    OutArcIt nextArc() const
alpar@209
   504
    {
alpar@100
   505
      return _stack_head>=0?_stack[_stack_head]:INVALID;
alpar@100
   506
    }
alpar@100
   507
kpeter@405
   508
    ///Returns \c false if there are nodes to be processed.
kpeter@405
   509
kpeter@405
   510
    ///Returns \c false if there are nodes to be processed
kpeter@405
   511
    ///in the queue (stack).
kpeter@244
   512
    bool emptyQueue() const { return _stack_head<0; }
kpeter@244
   513
alpar@100
   514
    ///Returns the number of the nodes to be processed.
alpar@209
   515
kpeter@405
   516
    ///Returns the number of the nodes to be processed
kpeter@405
   517
    ///in the queue (stack).
kpeter@244
   518
    int queueSize() const { return _stack_head+1; }
alpar@209
   519
alpar@100
   520
    ///Executes the algorithm.
alpar@100
   521
alpar@100
   522
    ///Executes the algorithm.
alpar@100
   523
    ///
kpeter@244
   524
    ///This method runs the %DFS algorithm from the root node
kpeter@244
   525
    ///in order to compute the DFS path to each node.
alpar@100
   526
    ///
kpeter@244
   527
    /// The algorithm computes
kpeter@244
   528
    ///- the %DFS tree,
kpeter@244
   529
    ///- the distance of each node from the root in the %DFS tree.
alpar@100
   530
    ///
kpeter@244
   531
    ///\pre init() must be called and a root node should be
kpeter@244
   532
    ///added with addSource() before using this function.
kpeter@244
   533
    ///
kpeter@244
   534
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
kpeter@244
   535
    ///\code
kpeter@244
   536
    ///  while ( !d.emptyQueue() ) {
kpeter@244
   537
    ///    d.processNextArc();
kpeter@244
   538
    ///  }
kpeter@244
   539
    ///\endcode
alpar@100
   540
    void start()
alpar@100
   541
    {
alpar@100
   542
      while ( !emptyQueue() ) processNextArc();
alpar@100
   543
    }
alpar@209
   544
kpeter@244
   545
    ///Executes the algorithm until the given target node is reached.
alpar@100
   546
kpeter@244
   547
    ///Executes the algorithm until the given target node is reached.
alpar@100
   548
    ///
kpeter@244
   549
    ///This method runs the %DFS algorithm from the root node
kpeter@286
   550
    ///in order to compute the DFS path to \c t.
alpar@100
   551
    ///
kpeter@244
   552
    ///The algorithm computes
kpeter@286
   553
    ///- the %DFS path to \c t,
kpeter@286
   554
    ///- the distance of \c t from the root in the %DFS tree.
alpar@100
   555
    ///
kpeter@244
   556
    ///\pre init() must be called and a root node should be
kpeter@244
   557
    ///added with addSource() before using this function.
kpeter@286
   558
    void start(Node t)
alpar@100
   559
    {
kpeter@286
   560
      while ( !emptyQueue() && G->target(_stack[_stack_head])!=t )
alpar@209
   561
        processNextArc();
alpar@100
   562
    }
alpar@209
   563
alpar@100
   564
    ///Executes the algorithm until a condition is met.
alpar@100
   565
alpar@100
   566
    ///Executes the algorithm until a condition is met.
alpar@100
   567
    ///
kpeter@244
   568
    ///This method runs the %DFS algorithm from the root node
kpeter@244
   569
    ///until an arc \c a with <tt>am[a]</tt> true is found.
alpar@100
   570
    ///
kpeter@244
   571
    ///\param am A \c bool (or convertible) arc map. The algorithm
kpeter@244
   572
    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
alpar@100
   573
    ///
kpeter@244
   574
    ///\return The reached arc \c a with <tt>am[a]</tt> true or
alpar@100
   575
    ///\c INVALID if no such arc was found.
alpar@100
   576
    ///
kpeter@244
   577
    ///\pre init() must be called and a root node should be
kpeter@244
   578
    ///added with addSource() before using this function.
kpeter@244
   579
    ///
kpeter@244
   580
    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
alpar@100
   581
    ///not a node map.
kpeter@244
   582
    template<class ArcBoolMap>
kpeter@244
   583
    Arc start(const ArcBoolMap &am)
alpar@100
   584
    {
kpeter@244
   585
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
alpar@100
   586
        processNextArc();
alpar@100
   587
      return emptyQueue() ? INVALID : _stack[_stack_head];
alpar@100
   588
    }
alpar@100
   589
kpeter@286
   590
    ///Runs the algorithm from the given source node.
alpar@209
   591
kpeter@244
   592
    ///This method runs the %DFS algorithm from node \c s
kpeter@244
   593
    ///in order to compute the DFS path to each node.
alpar@100
   594
    ///
kpeter@244
   595
    ///The algorithm computes
kpeter@244
   596
    ///- the %DFS tree,
kpeter@244
   597
    ///- the distance of each node from the root in the %DFS tree.
kpeter@244
   598
    ///
kpeter@244
   599
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
alpar@100
   600
    ///\code
alpar@100
   601
    ///  d.init();
kpeter@244
   602
    ///  d.addSource(s);
kpeter@244
   603
    ///  d.start();
kpeter@244
   604
    ///\endcode
kpeter@244
   605
    void run(Node s) {
kpeter@244
   606
      init();
kpeter@244
   607
      addSource(s);
kpeter@244
   608
      start();
kpeter@244
   609
    }
kpeter@244
   610
kpeter@244
   611
    ///Finds the %DFS path between \c s and \c t.
kpeter@244
   612
kpeter@244
   613
    ///This method runs the %DFS algorithm from node \c s
kpeter@286
   614
    ///in order to compute the DFS path to node \c t
kpeter@286
   615
    ///(it stops searching when \c t is processed)
kpeter@244
   616
    ///
kpeter@286
   617
    ///\return \c true if \c t is reachable form \c s.
kpeter@244
   618
    ///
kpeter@244
   619
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
kpeter@244
   620
    ///just a shortcut of the following code.
kpeter@244
   621
    ///\code
kpeter@244
   622
    ///  d.init();
kpeter@244
   623
    ///  d.addSource(s);
kpeter@244
   624
    ///  d.start(t);
kpeter@244
   625
    ///\endcode
kpeter@286
   626
    bool run(Node s,Node t) {
kpeter@244
   627
      init();
kpeter@244
   628
      addSource(s);
kpeter@244
   629
      start(t);
kpeter@286
   630
      return reached(t);
kpeter@244
   631
    }
kpeter@244
   632
kpeter@244
   633
    ///Runs the algorithm to visit all nodes in the digraph.
kpeter@244
   634
kpeter@244
   635
    ///This method runs the %DFS algorithm in order to compute the
kpeter@244
   636
    ///%DFS path to each node.
kpeter@244
   637
    ///
kpeter@244
   638
    ///The algorithm computes
kpeter@405
   639
    ///- the %DFS tree (forest),
kpeter@405
   640
    ///- the distance of each node from the root(s) in the %DFS tree.
kpeter@244
   641
    ///
kpeter@244
   642
    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
kpeter@244
   643
    ///\code
kpeter@244
   644
    ///  d.init();
kpeter@244
   645
    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
kpeter@244
   646
    ///    if (!d.reached(n)) {
kpeter@244
   647
    ///      d.addSource(n);
alpar@100
   648
    ///      d.start();
alpar@100
   649
    ///    }
alpar@100
   650
    ///  }
alpar@100
   651
    ///\endcode
alpar@100
   652
    void run() {
alpar@100
   653
      init();
alpar@100
   654
      for (NodeIt it(*G); it != INVALID; ++it) {
alpar@100
   655
        if (!reached(it)) {
alpar@100
   656
          addSource(it);
alpar@100
   657
          start();
alpar@100
   658
        }
alpar@100
   659
      }
alpar@100
   660
    }
alpar@100
   661
alpar@100
   662
    ///@}
alpar@100
   663
alpar@100
   664
    ///\name Query Functions
kpeter@405
   665
    ///The results of the DFS algorithm can be obtained using these
alpar@100
   666
    ///functions.\n
kpeter@405
   667
    ///Either \ref run(Node) "run()" or \ref start() should be called
kpeter@405
   668
    ///before using them.
alpar@209
   669
alpar@100
   670
    ///@{
alpar@100
   671
kpeter@244
   672
    ///The DFS path to a node.
alpar@100
   673
kpeter@244
   674
    ///Returns the DFS path to a node.
kpeter@244
   675
    ///
kpeter@405
   676
    ///\warning \c t should be reached from the root(s).
kpeter@244
   677
    ///
kpeter@405
   678
    ///\pre Either \ref run(Node) "run()" or \ref init()
kpeter@405
   679
    ///must be called before using this function.
kpeter@244
   680
    Path path(Node t) const { return Path(*G, *_pred, t); }
alpar@209
   681
kpeter@405
   682
    ///The distance of a node from the root(s).
alpar@100
   683
kpeter@405
   684
    ///Returns the distance of a node from the root(s).
kpeter@244
   685
    ///
kpeter@405
   686
    ///\warning If node \c v is not reached from the root(s), then
kpeter@244
   687
    ///the return value of this function is undefined.
kpeter@244
   688
    ///
kpeter@405
   689
    ///\pre Either \ref run(Node) "run()" or \ref init()
kpeter@405
   690
    ///must be called before using this function.
alpar@100
   691
    int dist(Node v) const { return (*_dist)[v]; }
alpar@100
   692
kpeter@244
   693
    ///Returns the 'previous arc' of the %DFS tree for a node.
alpar@100
   694
kpeter@244
   695
    ///This function returns the 'previous arc' of the %DFS tree for the
kpeter@405
   696
    ///node \c v, i.e. it returns the last arc of a %DFS path from a
kpeter@405
   697
    ///root to \c v. It is \c INVALID if \c v is not reached from the
kpeter@405
   698
    ///root(s) or if \c v is a root.
kpeter@244
   699
    ///
kpeter@244
   700
    ///The %DFS tree used here is equal to the %DFS tree used in
alpar@100
   701
    ///\ref predNode().
kpeter@244
   702
    ///
kpeter@405
   703
    ///\pre Either \ref run(Node) "run()" or \ref init()
kpeter@405
   704
    ///must be called before using this function.
alpar@100
   705
    Arc predArc(Node v) const { return (*_pred)[v];}
alpar@100
   706
alpar@100
   707
    ///Returns the 'previous node' of the %DFS tree.
alpar@100
   708
kpeter@244
   709
    ///This function returns the 'previous node' of the %DFS
kpeter@244
   710
    ///tree for the node \c v, i.e. it returns the last but one node
kpeter@405
   711
    ///from a %DFS path from a root to \c v. It is \c INVALID
kpeter@405
   712
    ///if \c v is not reached from the root(s) or if \c v is a root.
kpeter@244
   713
    ///
kpeter@244
   714
    ///The %DFS tree used here is equal to the %DFS tree used in
kpeter@244
   715
    ///\ref predArc().
kpeter@244
   716
    ///
kpeter@405
   717
    ///\pre Either \ref run(Node) "run()" or \ref init()
kpeter@405
   718
    ///must be called before using this function.
alpar@100
   719
    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
alpar@209
   720
                                  G->source((*_pred)[v]); }
alpar@209
   721
kpeter@244
   722
    ///\brief Returns a const reference to the node map that stores the
kpeter@244
   723
    ///distances of the nodes.
kpeter@244
   724
    ///
kpeter@244
   725
    ///Returns a const reference to the node map that stores the
kpeter@244
   726
    ///distances of the nodes calculated by the algorithm.
kpeter@244
   727
    ///
kpeter@405
   728
    ///\pre Either \ref run(Node) "run()" or \ref init()
kpeter@244
   729
    ///must be called before using this function.
alpar@100
   730
    const DistMap &distMap() const { return *_dist;}
alpar@209
   731
kpeter@244
   732
    ///\brief Returns a const reference to the node map that stores the
kpeter@244
   733
    ///predecessor arcs.
kpeter@244
   734
    ///
kpeter@244
   735
    ///Returns a const reference to the node map that stores the predecessor
kpeter@244
   736
    ///arcs, which form the DFS tree.
kpeter@244
   737
    ///
kpeter@405
   738
    ///\pre Either \ref run(Node) "run()" or \ref init()
alpar@100
   739
    ///must be called before using this function.
alpar@100
   740
    const PredMap &predMap() const { return *_pred;}
alpar@209
   741
kpeter@405
   742
    ///Checks if a node is reached from the root(s).
alpar@100
   743
kpeter@405
   744
    ///Returns \c true if \c v is reached from the root(s).
kpeter@405
   745
    ///
kpeter@405
   746
    ///\pre Either \ref run(Node) "run()" or \ref init()
alpar@100
   747
    ///must be called before using this function.
kpeter@244
   748
    bool reached(Node v) const { return (*_reached)[v]; }
alpar@209
   749
alpar@100
   750
    ///@}
alpar@100
   751
  };
alpar@100
   752
kpeter@244
   753
  ///Default traits class of dfs() function.
alpar@100
   754
kpeter@244
   755
  ///Default traits class of dfs() function.
kpeter@157
   756
  ///\tparam GR Digraph type.
alpar@100
   757
  template<class GR>
alpar@100
   758
  struct DfsWizardDefaultTraits
alpar@100
   759
  {
kpeter@244
   760
    ///The type of the digraph the algorithm runs on.
alpar@100
   761
    typedef GR Digraph;
kpeter@244
   762
kpeter@244
   763
    ///\brief The type of the map that stores the predecessor
alpar@100
   764
    ///arcs of the %DFS paths.
alpar@209
   765
    ///
kpeter@244
   766
    ///The type of the map that stores the predecessor
alpar@100
   767
    ///arcs of the %DFS paths.
alpar@100
   768
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
kpeter@278
   769
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
kpeter@301
   770
    ///Instantiates a PredMap.
alpar@209
   771
kpeter@301
   772
    ///This function instantiates a PredMap.
kpeter@244
   773
    ///\param g is the digraph, to which we would like to define the
kpeter@301
   774
    ///PredMap.
kpeter@244
   775
    static PredMap *createPredMap(const Digraph &g)
alpar@100
   776
    {
kpeter@278
   777
      return new PredMap(g);
alpar@100
   778
    }
alpar@100
   779
alpar@100
   780
    ///The type of the map that indicates which nodes are processed.
alpar@209
   781
alpar@100
   782
    ///The type of the map that indicates which nodes are processed.
alpar@100
   783
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
kpeter@278
   784
    ///By default it is a NullMap.
alpar@100
   785
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
kpeter@301
   786
    ///Instantiates a ProcessedMap.
alpar@209
   787
kpeter@301
   788
    ///This function instantiates a ProcessedMap.
alpar@100
   789
    ///\param g is the digraph, to which
kpeter@301
   790
    ///we would like to define the ProcessedMap.
alpar@100
   791
#ifdef DOXYGEN
kpeter@244
   792
    static ProcessedMap *createProcessedMap(const Digraph &g)
alpar@100
   793
#else
kpeter@244
   794
    static ProcessedMap *createProcessedMap(const Digraph &)
alpar@100
   795
#endif
alpar@100
   796
    {
alpar@100
   797
      return new ProcessedMap();
alpar@100
   798
    }
kpeter@244
   799
alpar@100
   800
    ///The type of the map that indicates which nodes are reached.
alpar@209
   801
alpar@100
   802
    ///The type of the map that indicates which nodes are reached.
kpeter@244
   803
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
alpar@100
   804
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
kpeter@301
   805
    ///Instantiates a ReachedMap.
alpar@209
   806
kpeter@301
   807
    ///This function instantiates a ReachedMap.
kpeter@244
   808
    ///\param g is the digraph, to which
kpeter@301
   809
    ///we would like to define the ReachedMap.
kpeter@244
   810
    static ReachedMap *createReachedMap(const Digraph &g)
alpar@100
   811
    {
kpeter@244
   812
      return new ReachedMap(g);
alpar@100
   813
    }
alpar@209
   814
kpeter@244
   815
    ///The type of the map that stores the distances of the nodes.
kpeter@244
   816
kpeter@244
   817
    ///The type of the map that stores the distances of the nodes.
alpar@100
   818
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
kpeter@278
   819
    typedef typename Digraph::template NodeMap<int> DistMap;
kpeter@301
   820
    ///Instantiates a DistMap.
alpar@209
   821
kpeter@301
   822
    ///This function instantiates a DistMap.
alpar@210
   823
    ///\param g is the digraph, to which we would like to define
kpeter@301
   824
    ///the DistMap
kpeter@244
   825
    static DistMap *createDistMap(const Digraph &g)
alpar@100
   826
    {
kpeter@278
   827
      return new DistMap(g);
alpar@100
   828
    }
kpeter@278
   829
kpeter@278
   830
    ///The type of the DFS paths.
kpeter@278
   831
kpeter@278
   832
    ///The type of the DFS paths.
kpeter@278
   833
    ///It must meet the \ref concepts::Path "Path" concept.
kpeter@278
   834
    typedef lemon::Path<Digraph> Path;
alpar@100
   835
  };
alpar@209
   836
kpeter@313
   837
  /// Default traits class used by DfsWizard
alpar@100
   838
alpar@100
   839
  /// To make it easier to use Dfs algorithm
kpeter@244
   840
  /// we have created a wizard class.
alpar@100
   841
  /// This \ref DfsWizard class needs default traits,
kpeter@244
   842
  /// as well as the \ref Dfs class.
alpar@100
   843
  /// The \ref DfsWizardBase is a class to be the default traits of the
alpar@100
   844
  /// \ref DfsWizard class.
alpar@100
   845
  template<class GR>
alpar@100
   846
  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
alpar@100
   847
  {
alpar@100
   848
alpar@100
   849
    typedef DfsWizardDefaultTraits<GR> Base;
alpar@100
   850
  protected:
kpeter@244
   851
    //The type of the nodes in the digraph.
alpar@100
   852
    typedef typename Base::Digraph::Node Node;
alpar@100
   853
kpeter@244
   854
    //Pointer to the digraph the algorithm runs on.
alpar@100
   855
    void *_g;
kpeter@244
   856
    //Pointer to the map of reached nodes.
alpar@100
   857
    void *_reached;
kpeter@244
   858
    //Pointer to the map of processed nodes.
alpar@100
   859
    void *_processed;
kpeter@244
   860
    //Pointer to the map of predecessors arcs.
alpar@100
   861
    void *_pred;
kpeter@244
   862
    //Pointer to the map of distances.
alpar@100
   863
    void *_dist;
kpeter@278
   864
    //Pointer to the DFS path to the target node.
kpeter@278
   865
    void *_path;
kpeter@278
   866
    //Pointer to the distance of the target node.
kpeter@278
   867
    int *_di;
alpar@209
   868
alpar@100
   869
    public:
alpar@100
   870
    /// Constructor.
alpar@209
   871
alpar@100
   872
    /// This constructor does not require parameters, therefore it initiates
kpeter@278
   873
    /// all of the attributes to \c 0.
alpar@100
   874
    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
kpeter@278
   875
                      _dist(0), _path(0), _di(0) {}
alpar@100
   876
alpar@100
   877
    /// Constructor.
alpar@209
   878
kpeter@278
   879
    /// This constructor requires one parameter,
kpeter@278
   880
    /// others are initiated to \c 0.
kpeter@244
   881
    /// \param g The digraph the algorithm runs on.
kpeter@278
   882
    DfsWizardBase(const GR &g) :
alpar@209
   883
      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
kpeter@278
   884
      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
alpar@100
   885
alpar@100
   886
  };
alpar@209
   887
kpeter@278
   888
  /// Auxiliary class for the function-type interface of DFS algorithm.
alpar@100
   889
kpeter@278
   890
  /// This auxiliary class is created to implement the
kpeter@278
   891
  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
kpeter@405
   892
  /// It does not have own \ref run(Node) "run()" method, it uses the
kpeter@405
   893
  /// functions and features of the plain \ref Dfs.
alpar@100
   894
  ///
kpeter@278
   895
  /// This class should only be used through the \ref dfs() function,
kpeter@278
   896
  /// which makes it easier to use the algorithm.
alpar@100
   897
  template<class TR>
alpar@100
   898
  class DfsWizard : public TR
alpar@100
   899
  {
alpar@100
   900
    typedef TR Base;
alpar@100
   901
kpeter@244
   902
    ///The type of the digraph the algorithm runs on.
alpar@100
   903
    typedef typename TR::Digraph Digraph;
kpeter@244
   904
alpar@100
   905
    typedef typename Digraph::Node Node;
alpar@100
   906
    typedef typename Digraph::NodeIt NodeIt;
alpar@100
   907
    typedef typename Digraph::Arc Arc;
alpar@100
   908
    typedef typename Digraph::OutArcIt OutArcIt;
alpar@209
   909
kpeter@244
   910
    ///\brief The type of the map that stores the predecessor
kpeter@278
   911
    ///arcs of the DFS paths.
kpeter@244
   912
    typedef typename TR::PredMap PredMap;
kpeter@244
   913
    ///\brief The type of the map that stores the distances of the nodes.
kpeter@244
   914
    typedef typename TR::DistMap DistMap;
kpeter@244
   915
    ///\brief The type of the map that indicates which nodes are reached.
alpar@100
   916
    typedef typename TR::ReachedMap ReachedMap;
kpeter@244
   917
    ///\brief The type of the map that indicates which nodes are processed.
alpar@100
   918
    typedef typename TR::ProcessedMap ProcessedMap;
kpeter@278
   919
    ///The type of the DFS paths
kpeter@278
   920
    typedef typename TR::Path Path;
alpar@100
   921
alpar@100
   922
  public:
kpeter@244
   923
alpar@100
   924
    /// Constructor.
alpar@100
   925
    DfsWizard() : TR() {}
alpar@100
   926
alpar@100
   927
    /// Constructor that requires parameters.
alpar@100
   928
alpar@100
   929
    /// Constructor that requires parameters.
alpar@100
   930
    /// These parameters will be the default values for the traits class.
kpeter@278
   931
    /// \param g The digraph the algorithm runs on.
kpeter@278
   932
    DfsWizard(const Digraph &g) :
kpeter@278
   933
      TR(g) {}
alpar@100
   934
alpar@100
   935
    ///Copy constructor
alpar@100
   936
    DfsWizard(const TR &b) : TR(b) {}
alpar@100
   937
alpar@100
   938
    ~DfsWizard() {}
alpar@100
   939
kpeter@278
   940
    ///Runs DFS algorithm from the given source node.
alpar@209
   941
kpeter@278
   942
    ///This method runs DFS algorithm from node \c s
kpeter@278
   943
    ///in order to compute the DFS path to each node.
kpeter@278
   944
    void run(Node s)
kpeter@278
   945
    {
kpeter@278
   946
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
kpeter@278
   947
      if (Base::_pred)
kpeter@278
   948
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
kpeter@278
   949
      if (Base::_dist)
kpeter@278
   950
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
kpeter@278
   951
      if (Base::_reached)
kpeter@278
   952
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
kpeter@278
   953
      if (Base::_processed)
kpeter@278
   954
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
kpeter@278
   955
      if (s!=INVALID)
kpeter@278
   956
        alg.run(s);
kpeter@278
   957
      else
kpeter@278
   958
        alg.run();
kpeter@278
   959
    }
kpeter@278
   960
kpeter@278
   961
    ///Finds the DFS path between \c s and \c t.
kpeter@278
   962
kpeter@278
   963
    ///This method runs DFS algorithm from node \c s
kpeter@278
   964
    ///in order to compute the DFS path to node \c t
kpeter@278
   965
    ///(it stops searching when \c t is processed).
kpeter@278
   966
    ///
kpeter@278
   967
    ///\return \c true if \c t is reachable form \c s.
kpeter@278
   968
    bool run(Node s, Node t)
kpeter@278
   969
    {
kpeter@278
   970
      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
kpeter@278
   971
      if (Base::_pred)
kpeter@278
   972
        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
kpeter@278
   973
      if (Base::_dist)
kpeter@278
   974
        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
kpeter@278
   975
      if (Base::_reached)
kpeter@278
   976
        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
kpeter@278
   977
      if (Base::_processed)
kpeter@278
   978
        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
kpeter@278
   979
      alg.run(s,t);
kpeter@278
   980
      if (Base::_path)
kpeter@278
   981
        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
kpeter@278
   982
      if (Base::_di)
kpeter@278
   983
        *Base::_di = alg.dist(t);
kpeter@278
   984
      return alg.reached(t);
kpeter@278
   985
      }
kpeter@278
   986
kpeter@278
   987
    ///Runs DFS algorithm to visit all nodes in the digraph.
kpeter@278
   988
kpeter@278
   989
    ///This method runs DFS algorithm in order to compute
kpeter@278
   990
    ///the DFS path to each node.
alpar@100
   991
    void run()
alpar@100
   992
    {
kpeter@278
   993
      run(INVALID);
kpeter@244
   994
    }
kpeter@244
   995
alpar@100
   996
    template<class T>
kpeter@257
   997
    struct SetPredMapBase : public Base {
alpar@100
   998
      typedef T PredMap;
alpar@100
   999
      static PredMap *createPredMap(const Digraph &) { return 0; };
kpeter@257
  1000
      SetPredMapBase(const TR &b) : TR(b) {}
alpar@100
  1001
    };
kpeter@278
  1002
    ///\brief \ref named-func-param "Named parameter"
kpeter@301
  1003
    ///for setting PredMap object.
alpar@100
  1004
    ///
kpeter@278
  1005
    ///\ref named-func-param "Named parameter"
kpeter@301
  1006
    ///for setting PredMap object.
alpar@100
  1007
    template<class T>
kpeter@257
  1008
    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
alpar@100
  1009
    {
alpar@100
  1010
      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
kpeter@257
  1011
      return DfsWizard<SetPredMapBase<T> >(*this);
alpar@100
  1012
    }
alpar@209
  1013
alpar@100
  1014
    template<class T>
kpeter@257
  1015
    struct SetReachedMapBase : public Base {
alpar@100
  1016
      typedef T ReachedMap;
alpar@100
  1017
      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
kpeter@257
  1018
      SetReachedMapBase(const TR &b) : TR(b) {}
alpar@100
  1019
    };
kpeter@278
  1020
    ///\brief \ref named-func-param "Named parameter"
kpeter@301
  1021
    ///for setting ReachedMap object.
alpar@100
  1022
    ///
kpeter@278
  1023
    /// \ref named-func-param "Named parameter"
kpeter@301
  1024
    ///for setting ReachedMap object.
alpar@100
  1025
    template<class T>
kpeter@257
  1026
    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
alpar@100
  1027
    {
deba@158
  1028
      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
kpeter@257
  1029
      return DfsWizard<SetReachedMapBase<T> >(*this);
alpar@100
  1030
    }
alpar@209
  1031
alpar@100
  1032
    template<class T>
kpeter@278
  1033
    struct SetDistMapBase : public Base {
kpeter@278
  1034
      typedef T DistMap;
kpeter@278
  1035
      static DistMap *createDistMap(const Digraph &) { return 0; };
kpeter@278
  1036
      SetDistMapBase(const TR &b) : TR(b) {}
kpeter@278
  1037
    };
kpeter@278
  1038
    ///\brief \ref named-func-param "Named parameter"
kpeter@301
  1039
    ///for setting DistMap object.
kpeter@278
  1040
    ///
kpeter@278
  1041
    /// \ref named-func-param "Named parameter"
kpeter@301
  1042
    ///for setting DistMap object.
kpeter@278
  1043
    template<class T>
kpeter@278
  1044
    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
kpeter@278
  1045
    {
kpeter@278
  1046
      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
kpeter@278
  1047
      return DfsWizard<SetDistMapBase<T> >(*this);
kpeter@278
  1048
    }
kpeter@278
  1049
kpeter@278
  1050
    template<class T>
kpeter@257
  1051
    struct SetProcessedMapBase : public Base {
alpar@100
  1052
      typedef T ProcessedMap;
alpar@100
  1053
      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
kpeter@257
  1054
      SetProcessedMapBase(const TR &b) : TR(b) {}
alpar@100
  1055
    };
kpeter@278
  1056
    ///\brief \ref named-func-param "Named parameter"
kpeter@301
  1057
    ///for setting ProcessedMap object.
alpar@100
  1058
    ///
kpeter@278
  1059
    /// \ref named-func-param "Named parameter"
kpeter@301
  1060
    ///for setting ProcessedMap object.
alpar@100
  1061
    template<class T>
kpeter@257
  1062
    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
alpar@100
  1063
    {
deba@158
  1064
      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
kpeter@257
  1065
      return DfsWizard<SetProcessedMapBase<T> >(*this);
alpar@100
  1066
    }
alpar@209
  1067
alpar@100
  1068
    template<class T>
kpeter@278
  1069
    struct SetPathBase : public Base {
kpeter@278
  1070
      typedef T Path;
kpeter@278
  1071
      SetPathBase(const TR &b) : TR(b) {}
alpar@100
  1072
    };
kpeter@278
  1073
    ///\brief \ref named-func-param "Named parameter"
kpeter@278
  1074
    ///for getting the DFS path to the target node.
alpar@100
  1075
    ///
kpeter@278
  1076
    ///\ref named-func-param "Named parameter"
kpeter@278
  1077
    ///for getting the DFS path to the target node.
alpar@100
  1078
    template<class T>
kpeter@278
  1079
    DfsWizard<SetPathBase<T> > path(const T &t)
alpar@100
  1080
    {
kpeter@278
  1081
      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
kpeter@278
  1082
      return DfsWizard<SetPathBase<T> >(*this);
kpeter@278
  1083
    }
kpeter@278
  1084
kpeter@278
  1085
    ///\brief \ref named-func-param "Named parameter"
kpeter@278
  1086
    ///for getting the distance of the target node.
kpeter@278
  1087
    ///
kpeter@278
  1088
    ///\ref named-func-param "Named parameter"
kpeter@278
  1089
    ///for getting the distance of the target node.
kpeter@278
  1090
    DfsWizard dist(const int &d)
kpeter@278
  1091
    {
kpeter@278
  1092
      Base::_di=const_cast<int*>(&d);
kpeter@278
  1093
      return *this;
alpar@100
  1094
    }
alpar@209
  1095
alpar@100
  1096
  };
alpar@209
  1097
kpeter@278
  1098
  ///Function-type interface for DFS algorithm.
alpar@100
  1099
alpar@100
  1100
  ///\ingroup search
kpeter@278
  1101
  ///Function-type interface for DFS algorithm.
alpar@100
  1102
  ///
kpeter@278
  1103
  ///This function also has several \ref named-func-param "named parameters",
alpar@100
  1104
  ///they are declared as the members of class \ref DfsWizard.
kpeter@278
  1105
  ///The following examples show how to use these parameters.
alpar@100
  1106
  ///\code
kpeter@278
  1107
  ///  // Compute the DFS tree
kpeter@278
  1108
  ///  dfs(g).predMap(preds).distMap(dists).run(s);
kpeter@278
  1109
  ///
kpeter@278
  1110
  ///  // Compute the DFS path from s to t
kpeter@278
  1111
  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
alpar@100
  1112
  ///\endcode
kpeter@405
  1113
  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
alpar@100
  1114
  ///to the end of the parameter list.
alpar@100
  1115
  ///\sa DfsWizard
alpar@100
  1116
  ///\sa Dfs
alpar@100
  1117
  template<class GR>
alpar@100
  1118
  DfsWizard<DfsWizardBase<GR> >
kpeter@278
  1119
  dfs(const GR &digraph)
alpar@100
  1120
  {
kpeter@278
  1121
    return DfsWizard<DfsWizardBase<GR> >(digraph);
alpar@100
  1122
  }
alpar@100
  1123
alpar@100
  1124
#ifdef DOXYGEN
kpeter@244
  1125
  /// \brief Visitor class for DFS.
alpar@209
  1126
  ///
kpeter@244
  1127
  /// This class defines the interface of the DfsVisit events, and
kpeter@244
  1128
  /// it could be the base of a real visitor class.
kpeter@492
  1129
  template <typename GR>
alpar@100
  1130
  struct DfsVisitor {
kpeter@492
  1131
    typedef GR Digraph;
alpar@100
  1132
    typedef typename Digraph::Arc Arc;
alpar@100
  1133
    typedef typename Digraph::Node Node;
kpeter@244
  1134
    /// \brief Called for the source node of the DFS.
alpar@209
  1135
    ///
kpeter@244
  1136
    /// This function is called for the source node of the DFS.
kpeter@244
  1137
    void start(const Node& node) {}
kpeter@244
  1138
    /// \brief Called when the source node is leaved.
kpeter@244
  1139
    ///
kpeter@244
  1140
    /// This function is called when the source node is leaved.
kpeter@244
  1141
    void stop(const Node& node) {}
kpeter@244
  1142
    /// \brief Called when a node is reached first time.
kpeter@244
  1143
    ///
kpeter@244
  1144
    /// This function is called when a node is reached first time.
kpeter@244
  1145
    void reach(const Node& node) {}
kpeter@244
  1146
    /// \brief Called when an arc reaches a new node.
kpeter@244
  1147
    ///
kpeter@244
  1148
    /// This function is called when the DFS finds an arc whose target node
kpeter@244
  1149
    /// is not reached yet.
alpar@100
  1150
    void discover(const Arc& arc) {}
kpeter@244
  1151
    /// \brief Called when an arc is examined but its target node is
alpar@100
  1152
    /// already discovered.
alpar@209
  1153
    ///
kpeter@244
  1154
    /// This function is called when an arc is examined but its target node is
alpar@100
  1155
    /// already discovered.
alpar@100
  1156
    void examine(const Arc& arc) {}
kpeter@244
  1157
    /// \brief Called when the DFS steps back from a node.
alpar@209
  1158
    ///
kpeter@244
  1159
    /// This function is called when the DFS steps back from a node.
kpeter@244
  1160
    void leave(const Node& node) {}
kpeter@244
  1161
    /// \brief Called when the DFS steps back on an arc.
alpar@209
  1162
    ///
kpeter@244
  1163
    /// This function is called when the DFS steps back on an arc.
kpeter@244
  1164
    void backtrack(const Arc& arc) {}
alpar@100
  1165
  };
alpar@100
  1166
#else
kpeter@492
  1167
  template <typename GR>
alpar@100
  1168
  struct DfsVisitor {
kpeter@492
  1169
    typedef GR Digraph;
alpar@100
  1170
    typedef typename Digraph::Arc Arc;
alpar@100
  1171
    typedef typename Digraph::Node Node;
alpar@100
  1172
    void start(const Node&) {}
alpar@100
  1173
    void stop(const Node&) {}
kpeter@244
  1174
    void reach(const Node&) {}
kpeter@244
  1175
    void discover(const Arc&) {}
kpeter@244
  1176
    void examine(const Arc&) {}
kpeter@244
  1177
    void leave(const Node&) {}
kpeter@244
  1178
    void backtrack(const Arc&) {}
alpar@100
  1179
alpar@100
  1180
    template <typename _Visitor>
alpar@100
  1181
    struct Constraints {
alpar@100
  1182
      void constraints() {
alpar@209
  1183
        Arc arc;
alpar@209
  1184
        Node node;
alpar@209
  1185
        visitor.start(node);
alpar@209
  1186
        visitor.stop(arc);
kpeter@244
  1187
        visitor.reach(node);
kpeter@244
  1188
        visitor.discover(arc);
kpeter@244
  1189
        visitor.examine(arc);
kpeter@244
  1190
        visitor.leave(node);
kpeter@244
  1191
        visitor.backtrack(arc);
alpar@100
  1192
      }
alpar@100
  1193
      _Visitor& visitor;
alpar@100
  1194
    };
alpar@100
  1195
  };
alpar@100
  1196
#endif
alpar@100
  1197
alpar@100
  1198
  /// \brief Default traits class of DfsVisit class.
alpar@100
  1199
  ///
alpar@100
  1200
  /// Default traits class of DfsVisit class.
kpeter@244
  1201
  /// \tparam _Digraph The type of the digraph the algorithm runs on.
kpeter@492
  1202
  template<class GR>
alpar@100
  1203
  struct DfsVisitDefaultTraits {
alpar@100
  1204
kpeter@244
  1205
    /// \brief The type of the digraph the algorithm runs on.
kpeter@492
  1206
    typedef GR Digraph;
alpar@100
  1207
alpar@100
  1208
    /// \brief The type of the map that indicates which nodes are reached.
alpar@209
  1209
    ///
alpar@100
  1210
    /// The type of the map that indicates which nodes are reached.
kpeter@244
  1211
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
alpar@100
  1212
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
alpar@100
  1213
kpeter@301
  1214
    /// \brief Instantiates a ReachedMap.
alpar@100
  1215
    ///
kpeter@301
  1216
    /// This function instantiates a ReachedMap.
alpar@100
  1217
    /// \param digraph is the digraph, to which
kpeter@301
  1218
    /// we would like to define the ReachedMap.
alpar@100
  1219
    static ReachedMap *createReachedMap(const Digraph &digraph) {
alpar@100
  1220
      return new ReachedMap(digraph);
alpar@100
  1221
    }
alpar@100
  1222
alpar@100
  1223
  };
alpar@209
  1224
alpar@100
  1225
  /// \ingroup search
kpeter@244
  1226
  ///
kpeter@492
  1227
  /// \brief DFS algorithm class with visitor interface.
kpeter@244
  1228
  ///
kpeter@492
  1229
  /// This class provides an efficient implementation of the DFS algorithm
alpar@100
  1230
  /// with visitor interface.
alpar@100
  1231
  ///
kpeter@492
  1232
  /// The DfsVisit class provides an alternative interface to the Dfs
alpar@100
  1233
  /// class. It works with callback mechanism, the DfsVisit object calls
kpeter@244
  1234
  /// the member functions of the \c Visitor class on every DFS event.
alpar@100
  1235
  ///
kpeter@252
  1236
  /// This interface of the DFS algorithm should be used in special cases
kpeter@252
  1237
  /// when extra actions have to be performed in connection with certain
kpeter@252
  1238
  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
kpeter@252
  1239
  /// instead.
kpeter@252
  1240
  ///
kpeter@492
  1241
  /// \tparam GR The type of the digraph the algorithm runs on.
kpeter@492
  1242
  /// The default type is \ref ListDigraph.
kpeter@492
  1243
  /// The value of GR is not used directly by \ref DfsVisit,
kpeter@492
  1244
  /// it is only passed to \ref DfsVisitDefaultTraits.
kpeter@492
  1245
  /// \tparam VS The Visitor type that is used by the algorithm.
kpeter@492
  1246
  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
kpeter@244
  1247
  /// does not observe the DFS events. If you want to observe the DFS
kpeter@244
  1248
  /// events, you should implement your own visitor class.
kpeter@492
  1249
  /// \tparam TR Traits class to set various data types used by the
alpar@100
  1250
  /// algorithm. The default traits class is
kpeter@492
  1251
  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
alpar@100
  1252
  /// See \ref DfsVisitDefaultTraits for the documentation of
kpeter@244
  1253
  /// a DFS visit traits class.
alpar@100
  1254
#ifdef DOXYGEN
kpeter@492
  1255
  template <typename GR, typename VS, typename TR>
alpar@100
  1256
#else
kpeter@492
  1257
  template <typename GR = ListDigraph,
kpeter@492
  1258
            typename VS = DfsVisitor<GR>,
kpeter@492
  1259
            typename TR = DfsVisitDefaultTraits<GR> >
alpar@100
  1260
#endif
alpar@100
  1261
  class DfsVisit {
alpar@100
  1262
  public:
alpar@209
  1263
kpeter@244
  1264
    ///The traits class.
kpeter@492
  1265
    typedef TR Traits;
alpar@100
  1266
kpeter@244
  1267
    ///The type of the digraph the algorithm runs on.
alpar@100
  1268
    typedef typename Traits::Digraph Digraph;
alpar@100
  1269
kpeter@244
  1270
    ///The visitor type used by the algorithm.
kpeter@492
  1271
    typedef VS Visitor;
alpar@100
  1272
kpeter@244
  1273
    ///The type of the map that indicates which nodes are reached.
alpar@100
  1274
    typedef typename Traits::ReachedMap ReachedMap;
alpar@100
  1275
alpar@100
  1276
  private:
alpar@100
  1277
alpar@100
  1278
    typedef typename Digraph::Node Node;
alpar@100
  1279
    typedef typename Digraph::NodeIt NodeIt;
alpar@100
  1280
    typedef typename Digraph::Arc Arc;
alpar@100
  1281
    typedef typename Digraph::OutArcIt OutArcIt;
alpar@100
  1282
kpeter@244
  1283
    //Pointer to the underlying digraph.
alpar@100
  1284
    const Digraph *_digraph;
kpeter@244
  1285
    //Pointer to the visitor object.
alpar@100
  1286
    Visitor *_visitor;
kpeter@244
  1287
    //Pointer to the map of reached status of the nodes.
alpar@100
  1288
    ReachedMap *_reached;
kpeter@244
  1289
    //Indicates if _reached is locally allocated (true) or not.
alpar@100
  1290
    bool local_reached;
alpar@100
  1291
alpar@100
  1292
    std::vector<typename Digraph::Arc> _stack;
alpar@100
  1293
    int _stack_head;
alpar@100
  1294
alpar@280
  1295
    //Creates the maps if necessary.
alpar@100
  1296
    void create_maps() {
alpar@100
  1297
      if(!_reached) {
alpar@209
  1298
        local_reached = true;
alpar@209
  1299
        _reached = Traits::createReachedMap(*_digraph);
alpar@100
  1300
      }
alpar@100
  1301
    }
alpar@100
  1302
alpar@100
  1303
  protected:
alpar@100
  1304
alpar@100
  1305
    DfsVisit() {}
alpar@209
  1306
alpar@100
  1307
  public:
alpar@100
  1308
alpar@100
  1309
    typedef DfsVisit Create;
alpar@100
  1310
kpeter@405
  1311
    /// \name Named Template Parameters
alpar@100
  1312
alpar@100
  1313
    ///@{
alpar@100
  1314
    template <class T>
kpeter@257
  1315
    struct SetReachedMapTraits : public Traits {
alpar@100
  1316
      typedef T ReachedMap;
alpar@100
  1317
      static ReachedMap *createReachedMap(const Digraph &digraph) {
deba@290
  1318
        LEMON_ASSERT(false, "ReachedMap is not initialized");
deba@290
  1319
        return 0; // ignore warnings
alpar@100
  1320
      }
alpar@100
  1321
    };
alpar@209
  1322
    /// \brief \ref named-templ-param "Named parameter" for setting
kpeter@244
  1323
    /// ReachedMap type.
alpar@100
  1324
    ///
kpeter@244
  1325
    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
alpar@100
  1326
    template <class T>
kpeter@257
  1327
    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
kpeter@257
  1328
                                            SetReachedMapTraits<T> > {
kpeter@257
  1329
      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
alpar@100
  1330
    };
alpar@100
  1331
    ///@}
alpar@100
  1332
alpar@209
  1333
  public:
alpar@209
  1334
alpar@100
  1335
    /// \brief Constructor.
alpar@100
  1336
    ///
alpar@100
  1337
    /// Constructor.
alpar@100
  1338
    ///
kpeter@244
  1339
    /// \param digraph The digraph the algorithm runs on.
kpeter@244
  1340
    /// \param visitor The visitor object of the algorithm.
alpar@209
  1341
    DfsVisit(const Digraph& digraph, Visitor& visitor)
alpar@100
  1342
      : _digraph(&digraph), _visitor(&visitor),
alpar@209
  1343
        _reached(0), local_reached(false) {}
alpar@209
  1344
alpar@100
  1345
    /// \brief Destructor.
alpar@100
  1346
    ~DfsVisit() {
alpar@100
  1347
      if(local_reached) delete _reached;
alpar@100
  1348
    }
alpar@100
  1349
kpeter@244
  1350
    /// \brief Sets the map that indicates which nodes are reached.
alpar@100
  1351
    ///
kpeter@244
  1352
    /// Sets the map that indicates which nodes are reached.
kpeter@405
  1353
    /// If you don't use this function before calling \ref run(Node) "run()"
kpeter@405
  1354
    /// or \ref init(), an instance will be allocated automatically.
kpeter@405
  1355
    /// The destructor deallocates this automatically allocated map,
kpeter@405
  1356
    /// of course.
alpar@100
  1357
    /// \return <tt> (*this) </tt>
alpar@100
  1358
    DfsVisit &reachedMap(ReachedMap &m) {
alpar@100
  1359
      if(local_reached) {
alpar@209
  1360
        delete _reached;
alpar@209
  1361
        local_reached=false;
alpar@100
  1362
      }
alpar@100
  1363
      _reached = &m;
alpar@100
  1364
      return *this;
alpar@100
  1365
    }
alpar@100
  1366
alpar@100
  1367
  public:
kpeter@244
  1368
kpeter@405
  1369
    /// \name Execution Control
kpeter@405
  1370
    /// The simplest way to execute the DFS algorithm is to use one of the
kpeter@405
  1371
    /// member functions called \ref run(Node) "run()".\n
kpeter@405
  1372
    /// If you need more control on the execution, first you have to call
kpeter@405
  1373
    /// \ref init(), then you can add a source node with \ref addSource()
kpeter@405
  1374
    /// and perform the actual computation with \ref start().
kpeter@405
  1375
    /// This procedure can be repeated if there are nodes that have not
kpeter@405
  1376
    /// been reached.
alpar@100
  1377
alpar@100
  1378
    /// @{
kpeter@244
  1379
alpar@100
  1380
    /// \brief Initializes the internal data structures.
alpar@100
  1381
    ///
alpar@100
  1382
    /// Initializes the internal data structures.
alpar@100
  1383
    void init() {
alpar@100
  1384
      create_maps();
alpar@100
  1385
      _stack.resize(countNodes(*_digraph));
alpar@100
  1386
      _stack_head = -1;
alpar@100
  1387
      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
alpar@209
  1388
        _reached->set(u, false);
alpar@100
  1389
      }
alpar@100
  1390
    }
alpar@209
  1391
kpeter@405
  1392
    /// \brief Adds a new source node.
alpar@100
  1393
    ///
kpeter@405
  1394
    /// Adds a new source node to the set of nodes to be processed.
kpeter@244
  1395
    ///
kpeter@405
  1396
    /// \pre The stack must be empty. Otherwise the algorithm gives
kpeter@405
  1397
    /// wrong results. (One of the outgoing arcs of all the source nodes
kpeter@405
  1398
    /// except for the last one will not be visited and distances will
kpeter@405
  1399
    /// also be wrong.)
kpeter@244
  1400
    void addSource(Node s)
kpeter@244
  1401
    {
kpeter@244
  1402
      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
alpar@100
  1403
      if(!(*_reached)[s]) {
alpar@209
  1404
          _reached->set(s,true);
alpar@209
  1405
          _visitor->start(s);
alpar@209
  1406
          _visitor->reach(s);
alpar@209
  1407
          Arc e;
alpar@209
  1408
          _digraph->firstOut(e, s);
alpar@209
  1409
          if (e != INVALID) {
alpar@209
  1410
            _stack[++_stack_head] = e;
alpar@209
  1411
          } else {
alpar@209
  1412
            _visitor->leave(s);
deba@419
  1413
            _visitor->stop(s);
alpar@209
  1414
          }
alpar@209
  1415
        }
alpar@100
  1416
    }
alpar@209
  1417
alpar@100
  1418
    /// \brief Processes the next arc.
alpar@100
  1419
    ///
alpar@100
  1420
    /// Processes the next arc.
alpar@100
  1421
    ///
alpar@100
  1422
    /// \return The processed arc.
alpar@100
  1423
    ///
kpeter@244
  1424
    /// \pre The stack must not be empty.
alpar@209
  1425
    Arc processNextArc() {
alpar@100
  1426
      Arc e = _stack[_stack_head];
alpar@100
  1427
      Node m = _digraph->target(e);
alpar@100
  1428
      if(!(*_reached)[m]) {
alpar@209
  1429
        _visitor->discover(e);
alpar@209
  1430
        _visitor->reach(m);
alpar@209
  1431
        _reached->set(m, true);
alpar@209
  1432
        _digraph->firstOut(_stack[++_stack_head], m);
alpar@100
  1433
      } else {
alpar@209
  1434
        _visitor->examine(e);
alpar@209
  1435
        m = _digraph->source(e);
alpar@209
  1436
        _digraph->nextOut(_stack[_stack_head]);
alpar@100
  1437
      }
alpar@100
  1438
      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
alpar@209
  1439
        _visitor->leave(m);
alpar@209
  1440
        --_stack_head;
alpar@209
  1441
        if (_stack_head >= 0) {
alpar@209
  1442
          _visitor->backtrack(_stack[_stack_head]);
alpar@209
  1443
          m = _digraph->source(_stack[_stack_head]);
alpar@209
  1444
          _digraph->nextOut(_stack[_stack_head]);
alpar@209
  1445
        } else {
alpar@209
  1446
          _visitor->stop(m);
alpar@209
  1447
        }
alpar@100
  1448
      }
alpar@100
  1449
      return e;
alpar@100
  1450
    }
alpar@100
  1451
alpar@100
  1452
    /// \brief Next arc to be processed.
alpar@100
  1453
    ///
alpar@100
  1454
    /// Next arc to be processed.
alpar@100
  1455
    ///
alpar@100
  1456
    /// \return The next arc to be processed or INVALID if the stack is
alpar@100
  1457
    /// empty.
kpeter@244
  1458
    Arc nextArc() const {
alpar@100
  1459
      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
alpar@100
  1460
    }
alpar@100
  1461
alpar@100
  1462
    /// \brief Returns \c false if there are nodes
kpeter@244
  1463
    /// to be processed.
alpar@100
  1464
    ///
alpar@100
  1465
    /// Returns \c false if there are nodes
kpeter@244
  1466
    /// to be processed in the queue (stack).
kpeter@244
  1467
    bool emptyQueue() const { return _stack_head < 0; }
alpar@100
  1468
alpar@100
  1469
    /// \brief Returns the number of the nodes to be processed.
alpar@100
  1470
    ///
kpeter@244
  1471
    /// Returns the number of the nodes to be processed in the queue (stack).
kpeter@244
  1472
    int queueSize() const { return _stack_head + 1; }
alpar@209
  1473
alpar@100
  1474
    /// \brief Executes the algorithm.
alpar@100
  1475
    ///
alpar@100
  1476
    /// Executes the algorithm.
alpar@100
  1477
    ///
kpeter@244
  1478
    /// This method runs the %DFS algorithm from the root node
kpeter@244
  1479
    /// in order to compute the %DFS path to each node.
kpeter@244
  1480
    ///
kpeter@244
  1481
    /// The algorithm computes
kpeter@244
  1482
    /// - the %DFS tree,
kpeter@244
  1483
    /// - the distance of each node from the root in the %DFS tree.
kpeter@244
  1484
    ///
kpeter@244
  1485
    /// \pre init() must be called and a root node should be
kpeter@244
  1486
    /// added with addSource() before using this function.
kpeter@244
  1487
    ///
kpeter@244
  1488
    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
kpeter@244
  1489
    /// \code
kpeter@244
  1490
    ///   while ( !d.emptyQueue() ) {
kpeter@244
  1491
    ///     d.processNextArc();
kpeter@244
  1492
    ///   }
kpeter@244
  1493
    /// \endcode
alpar@100
  1494
    void start() {
alpar@100
  1495
      while ( !emptyQueue() ) processNextArc();
alpar@100
  1496
    }
alpar@209
  1497
kpeter@244
  1498
    /// \brief Executes the algorithm until the given target node is reached.
alpar@100
  1499
    ///
kpeter@244
  1500
    /// Executes the algorithm until the given target node is reached.
alpar@100
  1501
    ///
kpeter@244
  1502
    /// This method runs the %DFS algorithm from the root node
kpeter@286
  1503
    /// in order to compute the DFS path to \c t.
kpeter@244
  1504
    ///
kpeter@244
  1505
    /// The algorithm computes
kpeter@286
  1506
    /// - the %DFS path to \c t,
kpeter@286
  1507
    /// - the distance of \c t from the root in the %DFS tree.
kpeter@244
  1508
    ///
kpeter@244
  1509
    /// \pre init() must be called and a root node should be added
alpar@100
  1510
    /// with addSource() before using this function.
kpeter@286
  1511
    void start(Node t) {
kpeter@286
  1512
      while ( !emptyQueue() && _digraph->target(_stack[_stack_head]) != t )
alpar@209
  1513
        processNextArc();
alpar@100
  1514
    }
alpar@209
  1515
alpar@100
  1516
    /// \brief Executes the algorithm until a condition is met.
alpar@100
  1517
    ///
alpar@100
  1518
    /// Executes the algorithm until a condition is met.
alpar@100
  1519
    ///
kpeter@244
  1520
    /// This method runs the %DFS algorithm from the root node
kpeter@244
  1521
    /// until an arc \c a with <tt>am[a]</tt> true is found.
kpeter@244
  1522
    ///
kpeter@244
  1523
    /// \param am A \c bool (or convertible) arc map. The algorithm
kpeter@244
  1524
    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
kpeter@244
  1525
    ///
kpeter@244
  1526
    /// \return The reached arc \c a with <tt>am[a]</tt> true or
kpeter@244
  1527
    /// \c INVALID if no such arc was found.
kpeter@244
  1528
    ///
kpeter@244
  1529
    /// \pre init() must be called and a root node should be added
alpar@100
  1530
    /// with addSource() before using this function.
alpar@100
  1531
    ///
kpeter@244
  1532
    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
alpar@100
  1533
    /// not a node map.
kpeter@244
  1534
    template <typename AM>
kpeter@244
  1535
    Arc start(const AM &am) {
kpeter@244
  1536
      while ( !emptyQueue() && !am[_stack[_stack_head]] )
alpar@100
  1537
        processNextArc();
alpar@100
  1538
      return emptyQueue() ? INVALID : _stack[_stack_head];
alpar@100
  1539
    }
alpar@100
  1540
kpeter@286
  1541
    /// \brief Runs the algorithm from the given source node.
alpar@100
  1542
    ///
kpeter@244
  1543
    /// This method runs the %DFS algorithm from node \c s.
kpeter@244
  1544
    /// in order to compute the DFS path to each node.
kpeter@244
  1545
    ///
kpeter@244
  1546
    /// The algorithm computes
kpeter@244
  1547
    /// - the %DFS tree,
kpeter@244
  1548
    /// - the distance of each node from the root in the %DFS tree.
kpeter@244
  1549
    ///
kpeter@244
  1550
    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
alpar@100
  1551
    ///\code
alpar@100
  1552
    ///   d.init();
alpar@100
  1553
    ///   d.addSource(s);
alpar@100
  1554
    ///   d.start();
alpar@100
  1555
    ///\endcode
alpar@100
  1556
    void run(Node s) {
alpar@100
  1557
      init();
alpar@100
  1558
      addSource(s);
alpar@100
  1559
      start();
alpar@100
  1560
    }
alpar@100
  1561
kpeter@244
  1562
    /// \brief Finds the %DFS path between \c s and \c t.
kpeter@244
  1563
kpeter@244
  1564
    /// This method runs the %DFS algorithm from node \c s
kpeter@286
  1565
    /// in order to compute the DFS path to node \c t
kpeter@286
  1566
    /// (it stops searching when \c t is processed).
kpeter@244
  1567
    ///
kpeter@286
  1568
    /// \return \c true if \c t is reachable form \c s.
kpeter@244
  1569
    ///
kpeter@244
  1570
    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
kpeter@244
  1571
    /// just a shortcut of the following code.
kpeter@244
  1572
    ///\code
kpeter@244
  1573
    ///   d.init();
kpeter@244
  1574
    ///   d.addSource(s);
kpeter@244
  1575
    ///   d.start(t);
kpeter@244
  1576
    ///\endcode
kpeter@286
  1577
    bool run(Node s,Node t) {
kpeter@244
  1578
      init();
kpeter@244
  1579
      addSource(s);
kpeter@244
  1580
      start(t);
kpeter@286
  1581
      return reached(t);
kpeter@244
  1582
    }
kpeter@244
  1583
kpeter@244
  1584
    /// \brief Runs the algorithm to visit all nodes in the digraph.
alpar@209
  1585
alpar@100
  1586
    /// This method runs the %DFS algorithm in order to
kpeter@244
  1587
    /// compute the %DFS path to each node.
alpar@100
  1588
    ///
kpeter@244
  1589
    /// The algorithm computes
kpeter@405
  1590
    /// - the %DFS tree (forest),
kpeter@405
  1591
    /// - the distance of each node from the root(s) in the %DFS tree.
kpeter@244
  1592
    ///
kpeter@244
  1593
    /// \note <tt>d.run()</tt> is just a shortcut of the following code.
alpar@100
  1594
    ///\code
kpeter@244
  1595
    ///   d.init();
kpeter@244
  1596
    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
kpeter@244
  1597
    ///     if (!d.reached(n)) {
kpeter@244
  1598
    ///       d.addSource(n);
kpeter@244
  1599
    ///       d.start();
kpeter@244
  1600
    ///     }
kpeter@244
  1601
    ///   }
alpar@100
  1602
    ///\endcode
alpar@100
  1603
    void run() {
alpar@100
  1604
      init();
alpar@100
  1605
      for (NodeIt it(*_digraph); it != INVALID; ++it) {
alpar@100
  1606
        if (!reached(it)) {
alpar@100
  1607
          addSource(it);
alpar@100
  1608
          start();
alpar@100
  1609
        }
alpar@100
  1610
      }
alpar@100
  1611
    }
kpeter@244
  1612
alpar@100
  1613
    ///@}
alpar@100
  1614
alpar@100
  1615
    /// \name Query Functions
kpeter@405
  1616
    /// The results of the DFS algorithm can be obtained using these
alpar@100
  1617
    /// functions.\n
kpeter@405
  1618
    /// Either \ref run(Node) "run()" or \ref start() should be called
kpeter@405
  1619
    /// before using them.
kpeter@405
  1620
alpar@100
  1621
    ///@{
kpeter@244
  1622
kpeter@405
  1623
    /// \brief Checks if a node is reached from the root(s).
alpar@100
  1624
    ///
kpeter@405
  1625
    /// Returns \c true if \c v is reached from the root(s).
kpeter@405
  1626
    ///
kpeter@405
  1627
    /// \pre Either \ref run(Node) "run()" or \ref init()
alpar@100
  1628
    /// must be called before using this function.
kpeter@420
  1629
    bool reached(Node v) const { return (*_reached)[v]; }
kpeter@244
  1630
alpar@100
  1631
    ///@}
kpeter@244
  1632
alpar@100
  1633
  };
alpar@100
  1634
alpar@100
  1635
} //END OF NAMESPACE LEMON
alpar@100
  1636
alpar@100
  1637
#endif