1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2009
 
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     9  * Permission to use, modify and distribute this software is granted
 
    10  * provided that this copyright notice appears in all copies. For
 
    11  * precise terms see the accompanying LICENSE file.
 
    13  * This software is provided "AS IS" with no warranty of any kind,
 
    14  * express or implied, and with no claim as to its suitability for any
 
    21 ///\brief Classes for representing paths in digraphs.
 
    30 #include <lemon/error.h>
 
    31 #include <lemon/core.h>
 
    32 #include <lemon/concepts/path.h>
 
    40   /// \brief A structure for representing directed paths in a digraph.
 
    42   /// A structure for representing directed path in a digraph.
 
    43   /// \tparam GR The digraph type in which the path is.
 
    45   /// In a sense, the path can be treated as a list of arcs. The
 
    46   /// lemon path type stores just this list. As a consequence, it
 
    47   /// cannot enumerate the nodes of the path and the source node of
 
    48   /// a zero length path is undefined.
 
    50   /// This implementation is a back and front insertable and erasable
 
    51   /// path type. It can be indexed in O(1) time. The front and back
 
    52   /// insertion and erase is done in O(1) (amortized) time. The
 
    53   /// implementation uses two vectors for storing the front and back
 
    55   template <typename GR>
 
    60     typedef typename Digraph::Arc Arc;
 
    62     /// \brief Default constructor
 
    64     /// Default constructor
 
    67     /// \brief Template copy constructor
 
    69     /// This constuctor initializes the path from any other path type.
 
    70     /// It simply makes a copy of the given path.
 
    71     template <typename CPath>
 
    72     Path(const CPath& cpath) {
 
    73       copyPath(*this, cpath);
 
    76     /// \brief Template copy assignment
 
    78     /// This operator makes a copy of a path of any other type.
 
    79     template <typename CPath>
 
    80     Path& operator=(const CPath& cpath) {
 
    81       copyPath(*this, cpath);
 
    85     /// \brief LEMON style iterator for path arcs
 
    87     /// This class is used to iterate on the arcs of the paths.
 
    91       /// \brief Default constructor
 
    93       /// \brief Invalid constructor
 
    94       ArcIt(Invalid) : path(0), idx(-1) {}
 
    95       /// \brief Initializate the iterator to the first arc of path
 
    96       ArcIt(const Path &_path)
 
    97         : path(&_path), idx(_path.empty() ? -1 : 0) {}
 
   101       ArcIt(const Path &_path, int _idx)
 
   102         : path(&_path), idx(_idx) {}
 
   106       /// \brief Conversion to Arc
 
   107       operator const Arc&() const {
 
   108         return path->nth(idx);
 
   112       ArcIt& operator++() {
 
   114         if (idx >= path->length()) idx = -1;
 
   118       /// \brief Comparison operator
 
   119       bool operator==(const ArcIt& e) const { return idx==e.idx; }
 
   120       /// \brief Comparison operator
 
   121       bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
 
   122       /// \brief Comparison operator
 
   123       bool operator<(const ArcIt& e) const { return idx<e.idx; }
 
   130     /// \brief Length of the path.
 
   131     int length() const { return head.size() + tail.size(); }
 
   132     /// \brief Return whether the path is empty.
 
   133     bool empty() const { return head.empty() && tail.empty(); }
 
   135     /// \brief Reset the path to an empty one.
 
   136     void clear() { head.clear(); tail.clear(); }
 
   138     /// \brief The nth arc.
 
   140     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 
   141     const Arc& nth(int n) const {
 
   142       return n < int(head.size()) ? *(head.rbegin() + n) :
 
   143         *(tail.begin() + (n - head.size()));
 
   146     /// \brief Initialize arc iterator to point to the nth arc
 
   148     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 
   149     ArcIt nthIt(int n) const {
 
   150       return ArcIt(*this, n);
 
   153     /// \brief The first arc of the path
 
   154     const Arc& front() const {
 
   155       return head.empty() ? tail.front() : head.back();
 
   158     /// \brief Add a new arc before the current path
 
   159     void addFront(const Arc& arc) {
 
   163     /// \brief Erase the first arc of the path
 
   169         int halfsize = tail.size() / 2;
 
   170         head.resize(halfsize);
 
   171         std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
 
   173         std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
 
   174         tail.resize(tail.size() - halfsize - 1);
 
   178     /// \brief The last arc of the path
 
   179     const Arc& back() const {
 
   180       return tail.empty() ? head.front() : tail.back();
 
   183     /// \brief Add a new arc behind the current path
 
   184     void addBack(const Arc& arc) {
 
   188     /// \brief Erase the last arc of the path
 
   193         int halfsize = head.size() / 2;
 
   194         tail.resize(halfsize);
 
   195         std::copy(head.begin() + 1, head.begin() + halfsize + 1,
 
   197         std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
 
   198         head.resize(head.size() - halfsize - 1);
 
   202     typedef True BuildTag;
 
   204     template <typename CPath>
 
   205     void build(const CPath& path) {
 
   206       int len = path.length();
 
   208       for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
 
   213     template <typename CPath>
 
   214     void buildRev(const CPath& path) {
 
   215       int len = path.length();
 
   217       for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
 
   223     typedef std::vector<Arc> Container;
 
   224     Container head, tail;
 
   228   /// \brief A structure for representing directed paths in a digraph.
 
   230   /// A structure for representing directed path in a digraph.
 
   231   /// \tparam GR The digraph type in which the path is.
 
   233   /// In a sense, the path can be treated as a list of arcs. The
 
   234   /// lemon path type stores just this list. As a consequence it
 
   235   /// cannot enumerate the nodes in the path and the zero length paths
 
   236   /// cannot store the source.
 
   238   /// This implementation is a just back insertable and erasable path
 
   239   /// type. It can be indexed in O(1) time. The back insertion and
 
   240   /// erasure is amortized O(1) time. This implementation is faster
 
   241   /// then the \c Path type because it use just one vector for the
 
   243   template <typename GR>
 
   248     typedef typename Digraph::Arc Arc;
 
   250     /// \brief Default constructor
 
   252     /// Default constructor
 
   255     /// \brief Template copy constructor
 
   257     /// This path can be initialized with any other path type. It just
 
   258     /// makes a copy of the given path.
 
   259     template <typename CPath>
 
   260     SimplePath(const CPath& cpath) {
 
   261       copyPath(*this, cpath);
 
   264     /// \brief Template copy assignment
 
   266     /// This path can be initialized with any other path type. It just
 
   267     /// makes a copy of the given path.
 
   268     template <typename CPath>
 
   269     SimplePath& operator=(const CPath& cpath) {
 
   270       copyPath(*this, cpath);
 
   274     /// \brief Iterator class to iterate on the arcs of the paths
 
   276     /// This class is used to iterate on the arcs of the paths
 
   278     /// Of course it converts to Digraph::Arc
 
   280       friend class SimplePath;
 
   282       /// Default constructor
 
   284       /// Invalid constructor
 
   285       ArcIt(Invalid) : path(0), idx(-1) {}
 
   286       /// \brief Initializate the constructor to the first arc of path
 
   287       ArcIt(const SimplePath &_path)
 
   288         : path(&_path), idx(_path.empty() ? -1 : 0) {}
 
   292       /// Constructor with starting point
 
   293       ArcIt(const SimplePath &_path, int _idx)
 
   294         : idx(_idx), path(&_path) {}
 
   298       ///Conversion to Digraph::Arc
 
   299       operator const Arc&() const {
 
   300         return path->nth(idx);
 
   304       ArcIt& operator++() {
 
   306         if (idx >= path->length()) idx = -1;
 
   310       /// Comparison operator
 
   311       bool operator==(const ArcIt& e) const { return idx==e.idx; }
 
   312       /// Comparison operator
 
   313       bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
 
   314       /// Comparison operator
 
   315       bool operator<(const ArcIt& e) const { return idx<e.idx; }
 
   318       const SimplePath *path;
 
   322     /// \brief Length of the path.
 
   323     int length() const { return data.size(); }
 
   324     /// \brief Return true if the path is empty.
 
   325     bool empty() const { return data.empty(); }
 
   327     /// \brief Reset the path to an empty one.
 
   328     void clear() { data.clear(); }
 
   330     /// \brief The nth arc.
 
   332     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 
   333     const Arc& nth(int n) const {
 
   337     /// \brief  Initializes arc iterator to point to the nth arc.
 
   338     ArcIt nthIt(int n) const {
 
   339       return ArcIt(*this, n);
 
   342     /// \brief The first arc of the path.
 
   343     const Arc& front() const {
 
   347     /// \brief The last arc of the path.
 
   348     const Arc& back() const {
 
   352     /// \brief Add a new arc behind the current path.
 
   353     void addBack(const Arc& arc) {
 
   357     /// \brief Erase the last arc of the path
 
   362     typedef True BuildTag;
 
   364     template <typename CPath>
 
   365     void build(const CPath& path) {
 
   366       int len = path.length();
 
   369       for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
 
   375     template <typename CPath>
 
   376     void buildRev(const CPath& path) {
 
   377       int len = path.length();
 
   380       for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
 
   387     typedef std::vector<Arc> Container;
 
   392   /// \brief A structure for representing directed paths in a digraph.
 
   394   /// A structure for representing directed path in a digraph.
 
   395   /// \tparam GR The digraph type in which the path is.
 
   397   /// In a sense, the path can be treated as a list of arcs. The
 
   398   /// lemon path type stores just this list. As a consequence it
 
   399   /// cannot enumerate the nodes in the path and the zero length paths
 
   400   /// cannot store the source.
 
   402   /// This implementation is a back and front insertable and erasable
 
   403   /// path type. It can be indexed in O(k) time, where k is the rank
 
   404   /// of the arc in the path. The length can be computed in O(n)
 
   405   /// time. The front and back insertion and erasure is O(1) time
 
   406   /// and it can be splited and spliced in O(1) time.
 
   407   template <typename GR>
 
   412     typedef typename Digraph::Arc Arc;
 
   416     // the std::list<> is incompatible
 
   417     // hard to create invalid iterator
 
   425     std::allocator<Node> alloc;
 
   429     /// \brief Default constructor
 
   431     /// Default constructor
 
   432     ListPath() : first(0), last(0) {}
 
   434     /// \brief Template copy constructor
 
   436     /// This path can be initialized with any other path type. It just
 
   437     /// makes a copy of the given path.
 
   438     template <typename CPath>
 
   439     ListPath(const CPath& cpath) : first(0), last(0) {
 
   440       copyPath(*this, cpath);
 
   443     /// \brief Destructor of the path
 
   445     /// Destructor of the path
 
   450     /// \brief Template copy assignment
 
   452     /// This path can be initialized with any other path type. It just
 
   453     /// makes a copy of the given path.
 
   454     template <typename CPath>
 
   455     ListPath& operator=(const CPath& cpath) {
 
   456       copyPath(*this, cpath);
 
   460     /// \brief Iterator class to iterate on the arcs of the paths
 
   462     /// This class is used to iterate on the arcs of the paths
 
   464     /// Of course it converts to Digraph::Arc
 
   466       friend class ListPath;
 
   468       /// Default constructor
 
   470       /// Invalid constructor
 
   471       ArcIt(Invalid) : path(0), node(0) {}
 
   472       /// \brief Initializate the constructor to the first arc of path
 
   473       ArcIt(const ListPath &_path)
 
   474         : path(&_path), node(_path.first) {}
 
   478       ArcIt(const ListPath &_path, Node *_node)
 
   479         : path(&_path), node(_node) {}
 
   484       ///Conversion to Digraph::Arc
 
   485       operator const Arc&() const {
 
   490       ArcIt& operator++() {
 
   495       /// Comparison operator
 
   496       bool operator==(const ArcIt& e) const { return node==e.node; }
 
   497       /// Comparison operator
 
   498       bool operator!=(const ArcIt& e) const { return node!=e.node; }
 
   499       /// Comparison operator
 
   500       bool operator<(const ArcIt& e) const { return node<e.node; }
 
   503       const ListPath *path;
 
   507     /// \brief The nth arc.
 
   509     /// This function looks for the nth arc in O(n) time.
 
   510     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 
   511     const Arc& nth(int n) const {
 
   513       for (int i = 0; i < n; ++i) {
 
   519     /// \brief Initializes arc iterator to point to the nth arc.
 
   520     ArcIt nthIt(int n) const {
 
   522       for (int i = 0; i < n; ++i) {
 
   525       return ArcIt(*this, node);
 
   528     /// \brief Length of the path.
 
   539     /// \brief Return true if the path is empty.
 
   540     bool empty() const { return first == 0; }
 
   542     /// \brief Reset the path to an empty one.
 
   546         alloc.destroy(first);
 
   547         alloc.deallocate(first, 1);
 
   552     /// \brief The first arc of the path
 
   553     const Arc& front() const {
 
   557     /// \brief Add a new arc before the current path
 
   558     void addFront(const Arc& arc) {
 
   559       Node *node = alloc.allocate(1);
 
   560       alloc.construct(node, Node());
 
   572     /// \brief Erase the first arc of the path
 
   582       alloc.deallocate(node, 1);
 
   585     /// \brief The last arc of the path.
 
   586     const Arc& back() const {
 
   590     /// \brief Add a new arc behind the current path.
 
   591     void addBack(const Arc& arc) {
 
   592       Node *node = alloc.allocate(1);
 
   593       alloc.construct(node, Node());
 
   605     /// \brief Erase the last arc of the path
 
   615       alloc.deallocate(node, 1);
 
   618     /// \brief Splice a path to the back of the current path.
 
   620     /// It splices \c tpath to the back of the current path and \c
 
   621     /// tpath becomes empty. The time complexity of this function is
 
   623     void spliceBack(ListPath& tpath) {
 
   626           last->next = tpath.first;
 
   627           tpath.first->prev = last;
 
   634       tpath.first = tpath.last = 0;
 
   637     /// \brief Splice a path to the front of the current path.
 
   639     /// It splices \c tpath before the current path and \c tpath
 
   640     /// becomes empty. The time complexity of this function
 
   642     void spliceFront(ListPath& tpath) {
 
   645           first->prev = tpath.last;
 
   646           tpath.last->next = first;
 
   653       tpath.first = tpath.last = 0;
 
   656     /// \brief Splice a path into the current path.
 
   658     /// It splices the \c tpath into the current path before the
 
   659     /// position of \c it iterator and \c tpath becomes empty. The
 
   660     /// time complexity of this function is O(1). If the \c it is
 
   661     /// \c INVALID then it will splice behind the current path.
 
   662     void splice(ArcIt it, ListPath& tpath) {
 
   665           tpath.first->prev = it.node->prev;
 
   667             it.node->prev->next = tpath.first;
 
   671           it.node->prev = tpath.last;
 
   672           tpath.last->next = it.node;
 
   677             last->next = tpath.first;
 
   678             tpath.first->prev = last;
 
   686       tpath.first = tpath.last = 0;
 
   689     /// \brief Split the current path.
 
   691     /// It splits the current path into two parts. The part before
 
   692     /// the iterator \c it will remain in the current path and the part
 
   694     /// \c it will put into \c tpath. If \c tpath have arcs
 
   695     /// before the operation they are removed first.  The time
 
   696     /// complexity of this function is O(1) plus the the time of emtying
 
   697     /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
 
   698     void split(ArcIt it, ListPath& tpath) {
 
   701         tpath.first = it.node;
 
   704           last = it.node->prev;
 
   714     typedef True BuildTag;
 
   716     template <typename CPath>
 
   717     void build(const CPath& path) {
 
   718       for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
 
   723     template <typename CPath>
 
   724     void buildRev(const CPath& path) {
 
   725       for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
 
   732   /// \brief A structure for representing directed paths in a digraph.
 
   734   /// A structure for representing directed path in a digraph.
 
   735   /// \tparam GR The digraph type in which the path is.
 
   737   /// In a sense, the path can be treated as a list of arcs. The
 
   738   /// lemon path type stores just this list. As a consequence it
 
   739   /// cannot enumerate the nodes in the path and the source node of
 
   740   /// a zero length path is undefined.
 
   742   /// This implementation is completly static, i.e. it can be copy constucted
 
   743   /// or copy assigned from another path, but otherwise it cannot be
 
   746   /// Being the the most memory efficient path type in LEMON,
 
   747   /// it is intented to be
 
   748   /// used when you want to store a large number of paths.
 
   749   template <typename GR>
 
   754     typedef typename Digraph::Arc Arc;
 
   756     /// \brief Default constructor
 
   758     /// Default constructor
 
   759     StaticPath() : len(0), arcs(0) {}
 
   761     /// \brief Template copy constructor
 
   763     /// This path can be initialized from any other path type.
 
   764     template <typename CPath>
 
   765     StaticPath(const CPath& cpath) : arcs(0) {
 
   766       copyPath(*this, cpath);
 
   769     /// \brief Destructor of the path
 
   771     /// Destructor of the path
 
   773       if (arcs) delete[] arcs;
 
   776     /// \brief Template copy assignment
 
   778     /// This path can be made equal to any other path type. It simply
 
   779     /// makes a copy of the given path.
 
   780     template <typename CPath>
 
   781     StaticPath& operator=(const CPath& cpath) {
 
   782       copyPath(*this, cpath);
 
   786     /// \brief Iterator class to iterate on the arcs of the paths
 
   788     /// This class is used to iterate on the arcs of the paths
 
   790     /// Of course it converts to Digraph::Arc
 
   792       friend class StaticPath;
 
   794       /// Default constructor
 
   796       /// Invalid constructor
 
   797       ArcIt(Invalid) : path(0), idx(-1) {}
 
   798       /// Initializate the constructor to the first arc of path
 
   799       ArcIt(const StaticPath &_path)
 
   800         : path(&_path), idx(_path.empty() ? -1 : 0) {}
 
   804       /// Constructor with starting point
 
   805       ArcIt(const StaticPath &_path, int _idx)
 
   806         : idx(_idx), path(&_path) {}
 
   810       ///Conversion to Digraph::Arc
 
   811       operator const Arc&() const {
 
   812         return path->nth(idx);
 
   816       ArcIt& operator++() {
 
   818         if (idx >= path->length()) idx = -1;
 
   822       /// Comparison operator
 
   823       bool operator==(const ArcIt& e) const { return idx==e.idx; }
 
   824       /// Comparison operator
 
   825       bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
 
   826       /// Comparison operator
 
   827       bool operator<(const ArcIt& e) const { return idx<e.idx; }
 
   830       const StaticPath *path;
 
   834     /// \brief The nth arc.
 
   836     /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
 
   837     const Arc& nth(int n) const {
 
   841     /// \brief The arc iterator pointing to the nth arc.
 
   842     ArcIt nthIt(int n) const {
 
   843       return ArcIt(*this, n);
 
   846     /// \brief The length of the path.
 
   847     int length() const { return len; }
 
   849     /// \brief Return true when the path is empty.
 
   850     int empty() const { return len == 0; }
 
   852     /// \brief Erase all arcs in the digraph.
 
   855       if (arcs) delete[] arcs;
 
   859     /// \brief The first arc of the path.
 
   860     const Arc& front() const {
 
   864     /// \brief The last arc of the path.
 
   865     const Arc& back() const {
 
   866       return arcs[len - 1];
 
   870     typedef True BuildTag;
 
   872     template <typename CPath>
 
   873     void build(const CPath& path) {
 
   877       for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
 
   883     template <typename CPath>
 
   884     void buildRev(const CPath& path) {
 
   888       for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
 
   899   ///////////////////////////////////////////////////////////////////////
 
   900   // Additional utilities
 
   901   ///////////////////////////////////////////////////////////////////////
 
   903   namespace _path_bits {
 
   905     template <typename Path, typename Enable = void>
 
   906     struct RevPathTagIndicator {
 
   907       static const bool value = false;
 
   910     template <typename Path>
 
   911     struct RevPathTagIndicator<
 
   913       typename enable_if<typename Path::RevPathTag, void>::type
 
   915       static const bool value = true;
 
   918     template <typename Path, typename Enable = void>
 
   919     struct BuildTagIndicator {
 
   920       static const bool value = false;
 
   923     template <typename Path>
 
   924     struct BuildTagIndicator<
 
   926       typename enable_if<typename Path::BuildTag, void>::type
 
   928       static const bool value = true;
 
   931     template <typename Target, typename Source,
 
   932               bool buildEnable = BuildTagIndicator<Target>::value>
 
   933     struct PathCopySelectorForward {
 
   934       static void copy(Target& target, const Source& source) {
 
   936         for (typename Source::ArcIt it(source); it != INVALID; ++it) {
 
   942     template <typename Target, typename Source>
 
   943     struct PathCopySelectorForward<Target, Source, true> {
 
   944       static void copy(Target& target, const Source& source) {
 
   946         target.build(source);
 
   950     template <typename Target, typename Source,
 
   951               bool buildEnable = BuildTagIndicator<Target>::value>
 
   952     struct PathCopySelectorBackward {
 
   953       static void copy(Target& target, const Source& source) {
 
   955         for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
 
   961     template <typename Target, typename Source>
 
   962     struct PathCopySelectorBackward<Target, Source, true> {
 
   963       static void copy(Target& target, const Source& source) {
 
   965         target.buildRev(source);
 
   970     template <typename Target, typename Source,
 
   971               bool revEnable = RevPathTagIndicator<Source>::value>
 
   972     struct PathCopySelector {
 
   973       static void copy(Target& target, const Source& source) {
 
   974         PathCopySelectorForward<Target, Source>::copy(target, source);
 
   978     template <typename Target, typename Source>
 
   979     struct PathCopySelector<Target, Source, true> {
 
   980       static void copy(Target& target, const Source& source) {
 
   981         PathCopySelectorBackward<Target, Source>::copy(target, source);
 
   988   /// \brief Make a copy of a path.
 
   990   ///  This function makes a copy of a path.
 
   991   template <typename Target, typename Source>
 
   992   void copyPath(Target& target, const Source& source) {
 
   993     checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
 
   994     _path_bits::PathCopySelector<Target, Source>::copy(target, source);
 
   997   /// \brief Check the consistency of a path.
 
   999   /// This function checks that the target of each arc is the same
 
  1000   /// as the source of the next one.
 
  1002   template <typename Digraph, typename Path>
 
  1003   bool checkPath(const Digraph& digraph, const Path& path) {
 
  1004     typename Path::ArcIt it(path);
 
  1005     if (it == INVALID) return true;
 
  1006     typename Digraph::Node node = digraph.target(it);
 
  1008     while (it != INVALID) {
 
  1009       if (digraph.source(it) != node) return false;
 
  1010       node = digraph.target(it);
 
  1016   /// \brief The source of a path
 
  1018   /// This function returns the source of the given path.
 
  1019   template <typename Digraph, typename Path>
 
  1020   typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
 
  1021     return digraph.source(path.front());
 
  1024   /// \brief The target of a path
 
  1026   /// This function returns the target of the given path.
 
  1027   template <typename Digraph, typename Path>
 
  1028   typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
 
  1029     return digraph.target(path.back());
 
  1032   /// \brief Class which helps to iterate through the nodes of a path
 
  1034   /// In a sense, the path can be treated as a list of arcs. The
 
  1035   /// lemon path type stores only this list. As a consequence, it
 
  1036   /// cannot enumerate the nodes in the path and the zero length paths
 
  1037   /// cannot have a source node.
 
  1039   /// This class implements the node iterator of a path structure. To
 
  1040   /// provide this feature, the underlying digraph should be passed to
 
  1041   /// the constructor of the iterator.
 
  1042   template <typename Path>
 
  1045     const typename Path::Digraph *_digraph;
 
  1046     typename Path::ArcIt _it;
 
  1047     typename Path::Digraph::Node _nd;
 
  1051     typedef typename Path::Digraph Digraph;
 
  1052     typedef typename Digraph::Node Node;
 
  1054     /// Default constructor
 
  1056     /// Invalid constructor
 
  1058       : _digraph(0), _it(INVALID), _nd(INVALID) {}
 
  1060     PathNodeIt(const Digraph& digraph, const Path& path)
 
  1061       : _digraph(&digraph), _it(path) {
 
  1062       _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
 
  1065     PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
 
  1066       : _digraph(&digraph), _it(path), _nd(src) {}
 
  1068     ///Conversion to Digraph::Node
 
  1069     operator Node() const {
 
  1074     PathNodeIt& operator++() {
 
  1075       if (_it == INVALID) _nd = INVALID;
 
  1077         _nd = _digraph->target(_it);
 
  1083     /// Comparison operator
 
  1084     bool operator==(const PathNodeIt& n) const {
 
  1085       return _it == n._it && _nd == n._nd;
 
  1087     /// Comparison operator
 
  1088     bool operator!=(const PathNodeIt& n) const {
 
  1089       return _it != n._it || _nd != n._nd;
 
  1091     /// Comparison operator
 
  1092     bool operator<(const PathNodeIt& n) const {
 
  1093       return (_it < n._it && _nd != INVALID);
 
  1100 } // namespace lemon
 
  1102 #endif // LEMON_PATH_H