lemon/dfs.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 787 c2230649a493
parent 786 e20173729589
child 825 75e6020b19b1
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

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