1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2013
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>
33 #include <lemon/bits/stl_iterators.h>
41 /// \brief A structure for representing directed paths in a digraph.
43 /// A structure for representing directed path in a digraph.
44 /// \tparam GR The digraph type in which the path is.
46 /// In a sense, the path can be treated as a list of arcs. The
47 /// LEMON path type stores just this list. As a consequence, it
48 /// cannot enumerate the nodes of the path and the source node of
49 /// a zero length path is undefined.
51 /// This implementation is a back and front insertable and erasable
52 /// path type. It can be indexed in O(1) time. The front and back
53 /// insertion and erase is done in O(1) (amortized) time. The
54 /// implementation uses two vectors for storing the front and back
56 template <typename GR>
61 typedef typename Digraph::Arc Arc;
63 /// \brief Default constructor
65 /// Default constructor
68 /// \brief Copy constructor
70 Path(const Path& cpath) {
71 pathCopy(cpath, *this);
74 /// \brief Template copy constructor
76 /// This constuctor initializes the path from any other path type.
77 /// It simply makes a copy of the given path.
78 template <typename CPath>
79 Path(const CPath& cpath) {
80 pathCopy(cpath, *this);
83 /// \brief Copy assignment
85 Path& operator=(const Path& cpath) {
86 pathCopy(cpath, *this);
90 /// \brief Template copy assignment
92 /// This operator makes a copy of a path of any other type.
93 template <typename CPath>
94 Path& operator=(const CPath& cpath) {
95 pathCopy(cpath, *this);
99 /// \brief LEMON style iterator for path arcs
101 /// This class is used to iterate on the arcs of the paths.
105 /// \brief Default constructor
107 /// \brief Invalid constructor
108 ArcIt(Invalid) : path(0), idx(-1) {}
109 /// \brief Initializate the iterator to the first arc of path
110 ArcIt(const Path &_path)
111 : path(&_path), idx(_path.empty() ? -1 : 0) {}
115 ArcIt(const Path &_path, int _idx)
116 : path(&_path), idx(_idx) {}
120 /// \brief Conversion to Arc
121 operator const Arc&() const {
122 return path->nth(idx);
126 ArcIt& operator++() {
128 if (idx >= path->length()) idx = -1;
132 /// \brief Comparison operator
133 bool operator==(const ArcIt& e) const { return idx==e.idx; }
134 /// \brief Comparison operator
135 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
136 /// \brief Comparison operator
137 bool operator<(const ArcIt& e) const { return idx<e.idx; }
144 /// \brief Gets the collection of the arcs of the path.
146 /// This function can be used for iterating on the
147 /// arcs of the path. It returns a wrapped
148 /// ArcIt, which looks like an STL container
149 /// (by having begin() and end()) which you can use in range-based
150 /// for loops, STL algorithms, etc.
151 /// For example you can write:
153 /// for(auto a: p.arcs())
156 LemonRangeWrapper1<ArcIt, Path> arcs() const {
157 return LemonRangeWrapper1<ArcIt, Path>(*this);
161 /// \brief Length of the path.
162 int length() const { return head.size() + tail.size(); }
163 /// \brief Return whether the path is empty.
164 bool empty() const { return head.empty() && tail.empty(); }
166 /// \brief Reset the path to an empty one.
167 void clear() { head.clear(); tail.clear(); }
169 /// \brief The n-th arc.
171 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
172 const Arc& nth(int n) const {
173 return n < int(head.size()) ? *(head.rbegin() + n) :
174 *(tail.begin() + (n - head.size()));
177 /// \brief Initialize arc iterator to point to the n-th arc
179 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
180 ArcIt nthIt(int n) const {
181 return ArcIt(*this, n);
184 /// \brief The first arc of the path
185 const Arc& front() const {
186 return head.empty() ? tail.front() : head.back();
189 /// \brief Add a new arc before the current path
190 void addFront(const Arc& arc) {
194 /// \brief Erase the first arc of the path
200 int halfsize = tail.size() / 2;
201 head.resize(halfsize);
202 std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
204 std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
205 tail.resize(tail.size() - halfsize - 1);
209 /// \brief The last arc of the path
210 const Arc& back() const {
211 return tail.empty() ? head.front() : tail.back();
214 /// \brief Add a new arc behind the current path
215 void addBack(const Arc& arc) {
219 /// \brief Erase the last arc of the path
224 int halfsize = head.size() / 2;
225 tail.resize(halfsize);
226 std::copy(head.begin() + 1, head.begin() + halfsize + 1,
228 std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
229 head.resize(head.size() - halfsize - 1);
233 typedef True BuildTag;
235 template <typename CPath>
236 void build(const CPath& path) {
237 int len = path.length();
239 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
244 template <typename CPath>
245 void buildRev(const CPath& path) {
246 int len = path.length();
248 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
254 typedef std::vector<Arc> Container;
255 Container head, tail;
259 /// \brief A structure for representing directed paths in a digraph.
261 /// A structure for representing directed path in a digraph.
262 /// \tparam GR The digraph type in which the path is.
264 /// In a sense, the path can be treated as a list of arcs. The
265 /// LEMON path type stores just this list. As a consequence it
266 /// cannot enumerate the nodes in the path and the zero length paths
267 /// cannot store the source.
269 /// This implementation is a just back insertable and erasable path
270 /// type. It can be indexed in O(1) time. The back insertion and
271 /// erasure is amortized O(1) time. This implementation is faster
272 /// then the \c Path type because it use just one vector for the
274 template <typename GR>
279 typedef typename Digraph::Arc Arc;
281 /// \brief Default constructor
283 /// Default constructor
286 /// \brief Copy constructor
288 SimplePath(const SimplePath& cpath) {
289 pathCopy(cpath, *this);
292 /// \brief Template copy constructor
294 /// This path can be initialized with any other path type. It just
295 /// makes a copy of the given path.
296 template <typename CPath>
297 SimplePath(const CPath& cpath) {
298 pathCopy(cpath, *this);
301 /// \brief Copy assignment
303 SimplePath& operator=(const SimplePath& cpath) {
304 pathCopy(cpath, *this);
308 /// \brief Template copy assignment
310 /// This path can be initialized with any other path type. It just
311 /// makes a copy of the given path.
312 template <typename CPath>
313 SimplePath& operator=(const CPath& cpath) {
314 pathCopy(cpath, *this);
318 /// \brief Iterator class to iterate on the arcs of the paths
320 /// This class is used to iterate on the arcs of the paths
322 /// Of course it converts to Digraph::Arc
324 friend class SimplePath;
326 /// Default constructor
328 /// Invalid constructor
329 ArcIt(Invalid) : path(0), idx(-1) {}
330 /// \brief Initializate the constructor to the first arc of path
331 ArcIt(const SimplePath &_path)
332 : path(&_path), idx(_path.empty() ? -1 : 0) {}
336 /// Constructor with starting point
337 ArcIt(const SimplePath &_path, int _idx)
338 : path(&_path), idx(_idx) {}
342 ///Conversion to Digraph::Arc
343 operator const Arc&() const {
344 return path->nth(idx);
348 ArcIt& operator++() {
350 if (idx >= path->length()) idx = -1;
354 /// Comparison operator
355 bool operator==(const ArcIt& e) const { return idx==e.idx; }
356 /// Comparison operator
357 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
358 /// Comparison operator
359 bool operator<(const ArcIt& e) const { return idx<e.idx; }
362 const SimplePath *path;
366 /// \brief Gets the collection of the arcs of the path.
368 /// This function can be used for iterating on the
369 /// arcs of the path. It returns a wrapped
370 /// ArcIt, which looks like an STL container
371 /// (by having begin() and end()) which you can use in range-based
372 /// for loops, STL algorithms, etc.
373 /// For example you can write:
375 /// for(auto a: p.arcs())
378 LemonRangeWrapper1<ArcIt, SimplePath> arcs() const {
379 return LemonRangeWrapper1<ArcIt, SimplePath>(*this);
383 /// \brief Length of the path.
384 int length() const { return data.size(); }
385 /// \brief Return true if the path is empty.
386 bool empty() const { return data.empty(); }
388 /// \brief Reset the path to an empty one.
389 void clear() { data.clear(); }
391 /// \brief The n-th arc.
393 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
394 const Arc& nth(int n) const {
398 /// \brief Initializes arc iterator to point to the n-th arc.
399 ArcIt nthIt(int n) const {
400 return ArcIt(*this, n);
403 /// \brief The first arc of the path.
404 const Arc& front() const {
408 /// \brief The last arc of the path.
409 const Arc& back() const {
413 /// \brief Add a new arc behind the current path.
414 void addBack(const Arc& arc) {
418 /// \brief Erase the last arc of the path
423 typedef True BuildTag;
425 template <typename CPath>
426 void build(const CPath& path) {
427 int len = path.length();
430 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
436 template <typename CPath>
437 void buildRev(const CPath& path) {
438 int len = path.length();
441 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
448 typedef std::vector<Arc> Container;
453 /// \brief A structure for representing directed paths in a digraph.
455 /// A structure for representing directed path in a digraph.
456 /// \tparam GR The digraph type in which the path is.
458 /// In a sense, the path can be treated as a list of arcs. The
459 /// LEMON path type stores just this list. As a consequence it
460 /// cannot enumerate the nodes in the path and the zero length paths
461 /// cannot store the source.
463 /// This implementation is a back and front insertable and erasable
464 /// path type. It can be indexed in O(k) time, where k is the rank
465 /// of the arc in the path. The length can be computed in O(n)
466 /// time. The front and back insertion and erasure is O(1) time
467 /// and it can be splited and spliced in O(1) time.
468 template <typename GR>
473 typedef typename Digraph::Arc Arc;
477 // the std::list<> is incompatible
478 // hard to create invalid iterator
486 std::allocator<Node> alloc;
490 /// \brief Default constructor
492 /// Default constructor
493 ListPath() : first(0), last(0) {}
495 /// \brief Copy constructor
497 ListPath(const ListPath& cpath) : first(0), last(0) {
498 pathCopy(cpath, *this);
501 /// \brief Template copy constructor
503 /// This path can be initialized with any other path type. It just
504 /// makes a copy of the given path.
505 template <typename CPath>
506 ListPath(const CPath& cpath) : first(0), last(0) {
507 pathCopy(cpath, *this);
510 /// \brief Destructor of the path
512 /// Destructor of the path
517 /// \brief Copy assignment
519 ListPath& operator=(const ListPath& cpath) {
520 pathCopy(cpath, *this);
524 /// \brief Template copy assignment
526 /// This path can be initialized with any other path type. It just
527 /// makes a copy of the given path.
528 template <typename CPath>
529 ListPath& operator=(const CPath& cpath) {
530 pathCopy(cpath, *this);
534 /// \brief Iterator class to iterate on the arcs of the paths
536 /// This class is used to iterate on the arcs of the paths
538 /// Of course it converts to Digraph::Arc
540 friend class ListPath;
542 /// Default constructor
544 /// Invalid constructor
545 ArcIt(Invalid) : path(0), node(0) {}
546 /// \brief Initializate the constructor to the first arc of path
547 ArcIt(const ListPath &_path)
548 : path(&_path), node(_path.first) {}
552 ArcIt(const ListPath &_path, Node *_node)
553 : path(&_path), node(_node) {}
558 ///Conversion to Digraph::Arc
559 operator const Arc&() const {
564 ArcIt& operator++() {
569 /// Comparison operator
570 bool operator==(const ArcIt& e) const { return node==e.node; }
571 /// Comparison operator
572 bool operator!=(const ArcIt& e) const { return node!=e.node; }
573 /// Comparison operator
574 bool operator<(const ArcIt& e) const { return node<e.node; }
577 const ListPath *path;
581 /// \brief Gets the collection of the arcs of the path.
583 /// This function can be used for iterating on the
584 /// arcs of the path. It returns a wrapped
585 /// ArcIt, which looks like an STL container
586 /// (by having begin() and end()) which you can use in range-based
587 /// for loops, STL algorithms, etc.
588 /// For example you can write:
590 /// for(auto a: p.arcs())
593 LemonRangeWrapper1<ArcIt, ListPath> arcs() const {
594 return LemonRangeWrapper1<ArcIt, ListPath>(*this);
598 /// \brief The n-th arc.
600 /// This function looks for the n-th arc in O(n) time.
601 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
602 const Arc& nth(int n) const {
604 for (int i = 0; i < n; ++i) {
610 /// \brief Initializes arc iterator to point to the n-th arc.
611 ArcIt nthIt(int n) const {
613 for (int i = 0; i < n; ++i) {
616 return ArcIt(*this, node);
619 /// \brief Length of the path.
630 /// \brief Return true if the path is empty.
631 bool empty() const { return first == 0; }
633 /// \brief Reset the path to an empty one.
637 alloc.destroy(first);
638 alloc.deallocate(first, 1);
643 /// \brief The first arc of the path
644 const Arc& front() const {
648 /// \brief Add a new arc before the current path
649 void addFront(const Arc& arc) {
650 Node *node = alloc.allocate(1);
651 alloc.construct(node, Node());
663 /// \brief Erase the first arc of the path
673 alloc.deallocate(node, 1);
676 /// \brief The last arc of the path.
677 const Arc& back() const {
681 /// \brief Add a new arc behind the current path.
682 void addBack(const Arc& arc) {
683 Node *node = alloc.allocate(1);
684 alloc.construct(node, Node());
696 /// \brief Erase the last arc of the path
706 alloc.deallocate(node, 1);
709 /// \brief Splice a path to the back of the current path.
711 /// It splices \c tpath to the back of the current path and \c
712 /// tpath becomes empty. The time complexity of this function is
714 void spliceBack(ListPath& tpath) {
717 last->next = tpath.first;
718 tpath.first->prev = last;
725 tpath.first = tpath.last = 0;
728 /// \brief Splice a path to the front of the current path.
730 /// It splices \c tpath before the current path and \c tpath
731 /// becomes empty. The time complexity of this function
733 void spliceFront(ListPath& tpath) {
736 first->prev = tpath.last;
737 tpath.last->next = first;
744 tpath.first = tpath.last = 0;
747 /// \brief Splice a path into the current path.
749 /// It splices the \c tpath into the current path before the
750 /// position of \c it iterator and \c tpath becomes empty. The
751 /// time complexity of this function is O(1). If the \c it is
752 /// \c INVALID then it will splice behind the current path.
753 void splice(ArcIt it, ListPath& tpath) {
756 tpath.first->prev = it.node->prev;
758 it.node->prev->next = tpath.first;
762 it.node->prev = tpath.last;
763 tpath.last->next = it.node;
768 last->next = tpath.first;
769 tpath.first->prev = last;
777 tpath.first = tpath.last = 0;
780 /// \brief Split the current path.
782 /// It splits the current path into two parts. The part before
783 /// the iterator \c it will remain in the current path and the part
785 /// \c it will put into \c tpath. If \c tpath have arcs
786 /// before the operation they are removed first. The time
787 /// complexity of this function is O(1) plus the the time of emtying
788 /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
789 void split(ArcIt it, ListPath& tpath) {
792 tpath.first = it.node;
795 last = it.node->prev;
805 typedef True BuildTag;
807 template <typename CPath>
808 void build(const CPath& path) {
809 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
814 template <typename CPath>
815 void buildRev(const CPath& path) {
816 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
823 /// \brief A structure for representing directed paths in a digraph.
825 /// A structure for representing directed path in a digraph.
826 /// \tparam GR The digraph type in which the path is.
828 /// In a sense, the path can be treated as a list of arcs. The
829 /// LEMON path type stores just this list. As a consequence it
830 /// cannot enumerate the nodes in the path and the source node of
831 /// a zero length path is undefined.
833 /// This implementation is completly static, i.e. it can be copy constucted
834 /// or copy assigned from another path, but otherwise it cannot be
837 /// Being the the most memory efficient path type in LEMON,
838 /// it is intented to be
839 /// used when you want to store a large number of paths.
840 template <typename GR>
845 typedef typename Digraph::Arc Arc;
847 /// \brief Default constructor
849 /// Default constructor
850 StaticPath() : len(0), _arcs(0) {}
852 /// \brief Copy constructor
854 StaticPath(const StaticPath& cpath) : _arcs(0) {
855 pathCopy(cpath, *this);
858 /// \brief Template copy constructor
860 /// This path can be initialized from any other path type.
861 template <typename CPath>
862 StaticPath(const CPath& cpath) : _arcs(0) {
863 pathCopy(cpath, *this);
866 /// \brief Destructor of the path
868 /// Destructor of the path
870 if (_arcs) delete[] _arcs;
873 /// \brief Copy assignment
875 StaticPath& operator=(const StaticPath& cpath) {
876 pathCopy(cpath, *this);
880 /// \brief Template copy assignment
882 /// This path can be made equal to any other path type. It simply
883 /// makes a copy of the given path.
884 template <typename CPath>
885 StaticPath& operator=(const CPath& cpath) {
886 pathCopy(cpath, *this);
890 /// \brief Iterator class to iterate on the arcs of the paths
892 /// This class is used to iterate on the arcs of the paths
894 /// Of course it converts to Digraph::Arc
896 friend class StaticPath;
898 /// Default constructor
900 /// Invalid constructor
901 ArcIt(Invalid) : path(0), idx(-1) {}
902 /// Initializate the constructor to the first arc of path
903 ArcIt(const StaticPath &_path)
904 : path(&_path), idx(_path.empty() ? -1 : 0) {}
908 /// Constructor with starting point
909 ArcIt(const StaticPath &_path, int _idx)
910 : idx(_idx), path(&_path) {}
914 ///Conversion to Digraph::Arc
915 operator const Arc&() const {
916 return path->nth(idx);
920 ArcIt& operator++() {
922 if (idx >= path->length()) idx = -1;
926 /// Comparison operator
927 bool operator==(const ArcIt& e) const { return idx==e.idx; }
928 /// Comparison operator
929 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
930 /// Comparison operator
931 bool operator<(const ArcIt& e) const { return idx<e.idx; }
934 const StaticPath *path;
938 /// \brief Gets the collection of the arcs of the path.
940 /// This function can be used for iterating on the
941 /// arcs of the path. It returns a wrapped
942 /// ArcIt, which looks like an STL container
943 /// (by having begin() and end()) which you can use in range-based
944 /// for loops, STL algorithms, etc.
945 /// For example you can write:
947 /// for(auto a: p.arcs())
950 LemonRangeWrapper1<ArcIt, StaticPath> arcs() const {
951 return LemonRangeWrapper1<ArcIt, StaticPath>(*this);
955 /// \brief The n-th arc.
957 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
958 const Arc& nth(int n) const {
962 /// \brief The arc iterator pointing to the n-th arc.
963 ArcIt nthIt(int n) const {
964 return ArcIt(*this, n);
967 /// \brief The length of the path.
968 int length() const { return len; }
970 /// \brief Return true when the path is empty.
971 int empty() const { return len == 0; }
973 /// \brief Erase all arcs in the digraph.
976 if (_arcs) delete[] _arcs;
980 /// \brief The first arc of the path.
981 const Arc& front() const {
985 /// \brief The last arc of the path.
986 const Arc& back() const {
987 return _arcs[len - 1];
991 typedef True BuildTag;
993 template <typename CPath>
994 void build(const CPath& path) {
996 _arcs = new Arc[len];
998 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
1004 template <typename CPath>
1005 void buildRev(const CPath& path) {
1006 len = path.length();
1007 _arcs = new Arc[len];
1009 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
1020 ///////////////////////////////////////////////////////////////////////
1021 // Additional utilities
1022 ///////////////////////////////////////////////////////////////////////
1024 namespace _path_bits {
1026 template <typename Path, typename Enable = void>
1027 struct RevPathTagIndicator {
1028 static const bool value = false;
1031 template <typename Path>
1032 struct RevPathTagIndicator<
1034 typename enable_if<typename Path::RevPathTag, void>::type
1036 static const bool value = true;
1039 template <typename Path, typename Enable = void>
1040 struct BuildTagIndicator {
1041 static const bool value = false;
1044 template <typename Path>
1045 struct BuildTagIndicator<
1047 typename enable_if<typename Path::BuildTag, void>::type
1049 static const bool value = true;
1052 template <typename From, typename To,
1053 bool buildEnable = BuildTagIndicator<To>::value>
1054 struct PathCopySelectorForward {
1055 static void copy(const From& from, To& to) {
1057 for (typename From::ArcIt it(from); it != INVALID; ++it) {
1063 template <typename From, typename To>
1064 struct PathCopySelectorForward<From, To, true> {
1065 static void copy(const From& from, To& to) {
1071 template <typename From, typename To,
1072 bool buildEnable = BuildTagIndicator<To>::value>
1073 struct PathCopySelectorBackward {
1074 static void copy(const From& from, To& to) {
1076 for (typename From::RevArcIt it(from); it != INVALID; ++it) {
1082 template <typename From, typename To>
1083 struct PathCopySelectorBackward<From, To, true> {
1084 static void copy(const From& from, To& to) {
1091 template <typename From, typename To,
1092 bool revEnable = RevPathTagIndicator<From>::value>
1093 struct PathCopySelector {
1094 static void copy(const From& from, To& to) {
1095 PathCopySelectorForward<From, To>::copy(from, to);
1099 template <typename From, typename To>
1100 struct PathCopySelector<From, To, true> {
1101 static void copy(const From& from, To& to) {
1102 PathCopySelectorBackward<From, To>::copy(from, to);
1109 /// \brief Make a copy of a path.
1111 /// This function makes a copy of a path.
1112 template <typename From, typename To>
1113 void pathCopy(const From& from, To& to) {
1114 checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
1115 _path_bits::PathCopySelector<From, To>::copy(from, to);
1118 /// \brief Deprecated version of \ref pathCopy().
1120 /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1121 template <typename To, typename From>
1122 void copyPath(To& to, const From& from) {
1126 /// \brief Check the consistency of a path.
1128 /// This function checks that the target of each arc is the same
1129 /// as the source of the next one.
1131 template <typename Digraph, typename Path>
1132 bool checkPath(const Digraph& digraph, const Path& path) {
1133 typename Path::ArcIt it(path);
1134 if (it == INVALID) return true;
1135 typename Digraph::Node node = digraph.target(it);
1137 while (it != INVALID) {
1138 if (digraph.source(it) != node) return false;
1139 node = digraph.target(it);
1145 /// \brief The source of a path
1147 /// This function returns the source node of the given path.
1148 /// If the path is empty, then it returns \c INVALID.
1149 template <typename Digraph, typename Path>
1150 typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1151 return path.empty() ? INVALID : digraph.source(path.front());
1154 /// \brief The target of a path
1156 /// This function returns the target node of the given path.
1157 /// If the path is empty, then it returns \c INVALID.
1158 template <typename Digraph, typename Path>
1159 typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1160 return path.empty() ? INVALID : digraph.target(path.back());
1163 /// \brief Class which helps to iterate through the nodes of a path
1165 /// In a sense, the path can be treated as a list of arcs. The
1166 /// LEMON path type stores only this list. As a consequence, it
1167 /// cannot enumerate the nodes in the path and the zero length paths
1168 /// cannot have a source node.
1170 /// This class implements the node iterator of a path structure. To
1171 /// provide this feature, the underlying digraph should be passed to
1172 /// the constructor of the iterator.
1173 template <typename Path>
1176 const typename Path::Digraph *_digraph;
1177 typename Path::ArcIt _it;
1178 typename Path::Digraph::Node _nd;
1182 typedef typename Path::Digraph Digraph;
1183 typedef typename Digraph::Node Node;
1185 /// Default constructor
1187 /// Invalid constructor
1189 : _digraph(0), _it(INVALID), _nd(INVALID) {}
1191 PathNodeIt(const Digraph& digraph, const Path& path)
1192 : _digraph(&digraph), _it(path) {
1193 _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1196 PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1197 : _digraph(&digraph), _it(path), _nd(src) {}
1199 ///Conversion to Digraph::Node
1200 operator Node() const {
1205 PathNodeIt& operator++() {
1206 if (_it == INVALID) _nd = INVALID;
1208 _nd = _digraph->target(_it);
1214 /// Comparison operator
1215 bool operator==(const PathNodeIt& n) const {
1216 return _it == n._it && _nd == n._nd;
1218 /// Comparison operator
1219 bool operator!=(const PathNodeIt& n) const {
1220 return _it != n._it || _nd != n._nd;
1222 /// Comparison operator
1223 bool operator<(const PathNodeIt& n) const {
1224 return (_it < n._it && _nd != INVALID);
1229 /// \brief Gets the collection of the nodes of the path.
1231 /// This function can be used for iterating on the
1232 /// nodes of the path. It returns a wrapped
1233 /// PathNodeIt, which looks like an STL container
1234 /// (by having begin() and end()) which you can use in range-based
1235 /// for loops, STL algorithms, etc.
1236 /// For example you can write:
1238 /// for(auto u: pathNodes(g,p))
1241 template<typename Path>
1242 LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>
1243 pathNodes(const typename Path::Digraph &g, const Path &p) {
1245 LemonRangeWrapper2<PathNodeIt<Path>, typename Path::Digraph, Path>(g,p);
1250 } // namespace lemon
1252 #endif // LEMON_PATH_H