* This file is a part of LEMON, a generic C++ optimization library
* Copyright (C) 2003-2008
* Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
* (Egervary Research Group on Combinatorial Optimization, EGRES).
* Permission to use, modify and distribute this software is granted
* provided that this copyright notice appears in all copies. For
* precise terms see the accompanying LICENSE file.
* This software is provided "AS IS" with no warranty of any kind,
* express or implied, and with no claim as to its suitability for any
///\brief Classes for representing paths in digraphs.
#include <lemon/path_utils.h>
#include <lemon/bits/invalid.h>
/// \brief A structure for representing directed paths in a digraph.
/// A structure for representing directed path in a digraph.
/// \param Digraph The digraph type in which the path is.
/// In a sense, the path can be treated as a list of arcs. The
/// lemon path type stores just this list. As a consequence it
/// cannot enumerate the nodes in the path and the zero length paths
/// cannot store the source.
/// This implementation is a back and front insertable and erasable
/// path type. It can be indexed in O(1) time. The front and back
/// insertion and erasure is amortized O(1) time. The
/// impelementation is based on two opposite organized vectors.
template <typename _Digraph>
typedef _Digraph Digraph;
typedef typename Digraph::Arc Arc;
/// \brief Default constructor
/// \brief Template copy constructor
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
Path(const CPath& cpath) {
/// \brief Template copy assignment
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
Path& operator=(const CPath& cpath) {
/// \brief Lemon style iterator for path arcs
/// This class is used to iterate on the arcs of the paths.
/// \brief Default constructor
/// \brief Invalid constructor
ArcIt(Invalid) : path(0), idx(-1) {}
/// \brief Initializate the constructor to the first arc of path
: path(&_path), idx(_path.empty() ? -1 : 0) {}
ArcIt(const Path &_path, int _idx)
: path(&_path), idx(_idx) {}
/// \brief Conversion to Arc
operator const Arc&() const {
if (idx >= path->length()) idx = -1;
/// \brief Comparison operator
bool operator==(const ArcIt& e) const { return idx==e.idx; }
/// \brief Comparison operator
bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
/// \brief Comparison operator
bool operator<(const ArcIt& e) const { return idx<e.idx; }
/// \brief Length of the path.
int length() const { return head.size() + tail.size(); }
/// \brief Returns whether the path is empty.
bool empty() const { return head.empty() && tail.empty(); }
/// \brief Resets the path to an empty path.
void clear() { head.clear(); tail.clear(); }
/// \brief Gives back the nth arc.
/// \pre n is in the [0..length() - 1] range
const Arc& nth(int n) const {
return n < int(head.size()) ? *(head.rbegin() + n) :
*(tail.begin() + (n - head.size()));
/// \brief Initializes arc iterator to point to the nth arc
/// \pre n is in the [0..length() - 1] range
ArcIt nthIt(int n) const {
/// \brief Gives back the first arc of the path
const Arc& front() const {
return head.empty() ? tail.front() : head.back();
/// \brief Add a new arc before the current path
void addFront(const Arc& arc) {
/// \brief Erase the first arc of the path
int halfsize = tail.size() / 2;
std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
tail.resize(tail.size() - halfsize - 1);
/// \brief Gives back the last arc of the path
const Arc& back() const {
return tail.empty() ? head.front() : tail.back();
/// \brief Add a new arc behind the current path
void addBack(const Arc& arc) {
/// \brief Erase the last arc of the path
int halfsize = head.size() / 2;
std::copy(head.begin() + 1, head.begin() + halfsize + 1,
std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
head.resize(head.size() - halfsize - 1);
template <typename CPath>
void build(const CPath& path) {
for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
template <typename CPath>
void buildRev(const CPath& path) {
for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
typedef std::vector<Arc> Container;
/// \brief A structure for representing directed paths in a digraph.
/// A structure for representing directed path in a digraph.
/// \param Digraph The digraph type in which the path is.
/// In a sense, the path can be treated as a list of arcs. The
/// lemon path type stores just this list. As a consequence it
/// cannot enumerate the nodes in the path and the zero length paths
/// cannot store the source.
/// This implementation is a just back insertable and erasable path
/// type. It can be indexed in O(1) time. The back insertion and
/// erasure is amortized O(1) time. This implementation is faster
/// then the \c Path type because it use just one vector for the
template <typename _Digraph>
typedef _Digraph Digraph;
typedef typename Digraph::Arc Arc;
/// \brief Default constructor
/// \brief Template copy constructor
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
SimplePath(const CPath& cpath) {
/// \brief Template copy assignment
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
SimplePath& operator=(const CPath& cpath) {
/// \brief Iterator class to iterate on the arcs of the paths
/// This class is used to iterate on the arcs of the paths
/// Of course it converts to Digraph::Arc
ArcIt(Invalid) : path(0), idx(-1) {}
/// \brief Initializate the constructor to the first arc of path
ArcIt(const SimplePath &_path)
: path(&_path), idx(_path.empty() ? -1 : 0) {}
/// Constructor with starting point
ArcIt(const SimplePath &_path, int _idx)
: idx(_idx), path(&_path) {}
///Conversion to Digraph::Arc
operator const Arc&() const {
if (idx >= path->length()) idx = -1;
bool operator==(const ArcIt& e) const { return idx==e.idx; }
bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
bool operator<(const ArcIt& e) const { return idx<e.idx; }
/// \brief Length of the path.
int length() const { return data.size(); }
/// \brief Returns whether the path is empty.
bool empty() const { return data.empty(); }
/// \brief Resets the path to an empty path.
void clear() { data.clear(); }
/// \brief Gives back the nth arc.
/// \pre n is in the [0..length() - 1] range
const Arc& nth(int n) const {
/// \brief Initializes arc iterator to point to the nth arc.
ArcIt nthIt(int n) const {
/// \brief Gives back the first arc of the path.
const Arc& front() const {
/// \brief Gives back the last arc of the path.
const Arc& back() const {
/// \brief Add a new arc behind the current path.
void addBack(const Arc& arc) {
/// \brief Erase the last arc of the path
template <typename CPath>
void build(const CPath& path) {
for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
template <typename CPath>
void buildRev(const CPath& path) {
for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
typedef std::vector<Arc> Container;
/// \brief A structure for representing directed paths in a digraph.
/// A structure for representing directed path in a digraph.
/// \param Digraph The digraph type in which the path is.
/// In a sense, the path can be treated as a list of arcs. The
/// lemon path type stores just this list. As a consequence it
/// cannot enumerate the nodes in the path and the zero length paths
/// cannot store the source.
/// This implementation is a back and front insertable and erasable
/// path type. It can be indexed in O(k) time, where k is the rank
/// of the arc in the path. The length can be computed in O(n)
/// time. The front and back insertion and erasure is O(1) time
/// and it can be splited and spliced in O(1) time.
template <typename _Digraph>
typedef _Digraph Digraph;
typedef typename Digraph::Arc Arc;
// the std::list<> is incompatible
// hard to create invalid iterator
std::allocator<Node> alloc;
/// \brief Default constructor
ListPath() : first(0), last(0) {}
/// \brief Template copy constructor
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
ListPath(const CPath& cpath) : first(0), last(0) {
/// \brief Destructor of the path
/// Destructor of the path
/// \brief Template copy assignment
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
ListPath& operator=(const CPath& cpath) {
/// \brief Iterator class to iterate on the arcs of the paths
/// This class is used to iterate on the arcs of the paths
/// Of course it converts to Digraph::Arc
ArcIt(Invalid) : path(0), node(0) {}
/// \brief Initializate the constructor to the first arc of path
ArcIt(const ListPath &_path)
: path(&_path), node(_path.first) {}
ArcIt(const ListPath &_path, Node *_node)
: path(&_path), node(_node) {}
///Conversion to Digraph::Arc
operator const Arc&() const {
bool operator==(const ArcIt& e) const { return node==e.node; }
bool operator!=(const ArcIt& e) const { return node!=e.node; }
bool operator<(const ArcIt& e) const { return node<e.node; }
/// \brief Gives back the nth arc.
/// Gives back the nth arc in O(n) time.
/// \pre n is in the [0..length() - 1] range
const Arc& nth(int n) const {
for (int i = 0; i < n; ++i) {
/// \brief Initializes arc iterator to point to the nth arc.
ArcIt nthIt(int n) const {
for (int i = 0; i < n; ++i) {
return ArcIt(*this, node);
/// \brief Length of the path.
/// \brief Returns whether the path is empty.
bool empty() const { return first == 0; }
/// \brief Resets the path to an empty path.
alloc.deallocate(first, 1);
/// \brief Gives back the first arc of the path
const Arc& front() const {
/// \brief Add a new arc before the current path
void addFront(const Arc& arc) {
Node *node = alloc.allocate(1);
alloc.construct(node, Node());
/// \brief Erase the first arc of the path
alloc.deallocate(node, 1);
/// \brief Gives back the last arc of the path.
const Arc& back() const {
/// \brief Add a new arc behind the current path.
void addBack(const Arc& arc) {
Node *node = alloc.allocate(1);
alloc.construct(node, Node());
/// \brief Erase the last arc of the path
alloc.deallocate(node, 1);
/// \brief Splicing the given path to the current path.
/// It splices the \c tpath to the back of the current path and \c
/// tpath becomes empty. The time complexity of this function is
void spliceBack(ListPath& tpath) {
last->next = tpath.first;
tpath.first->prev = last;
tpath.first = tpath.last = 0;
/// \brief Splicing the given path to the current path.
/// It splices the \c tpath before the current path and \c tpath
/// becomes empty. The time complexity of this function
void spliceFront(ListPath& tpath) {
first->prev = tpath.last;
tpath.last->next = first;
tpath.first = tpath.last = 0;
/// \brief Splicing the given path into the current path.
/// It splices the \c tpath into the current path before the
/// position of \c it iterator and \c tpath becomes empty. The
/// time complexity of this function is O(1). If the \c it is \c
/// INVALID then it will splice behind the current path.
void splice(ArcIt it, ListPath& tpath) {
tpath.first->prev = it.node->prev;
it.node->prev->next = tpath.first;
it.node->prev = tpath.last;
tpath.last->next = it.node;
last->next = tpath.first;
tpath.first->prev = last;
tpath.first = tpath.last = 0;
/// \brief Spliting the current path.
/// It splits the current path into two parts. The part before \c
/// it iterator will remain in the current path and the part from
/// the it will put into the \c tpath. If the \c tpath had arcs
/// before the operation they will be removed first. The time
/// complexity of this function is O(1) plus the clearing of \c
/// tpath. If the \c it is \c INVALID then it just clears \c
void split(ArcIt it, ListPath& tpath) {
template <typename CPath>
void build(const CPath& path) {
for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
template <typename CPath>
void buildRev(const CPath& path) {
for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
/// \brief A structure for representing directed paths in a digraph.
/// A structure for representing directed path in a digraph.
/// \param Digraph The digraph type in which the path is.
/// In a sense, the path can be treated as a list of arcs. The
/// lemon path type stores just this list. As a consequence it
/// cannot enumerate the nodes in the path and the zero length paths
/// cannot store the source.
/// This implementation is completly static, so it cannot be
/// modified exclude the assign an other path. It is intented to be
/// used when you want to store a large number of paths because it is
/// the most memory efficient path type in the lemon.
template <typename _Digraph>
typedef _Digraph Digraph;
typedef typename Digraph::Arc Arc;
/// \brief Default constructor
StaticPath() : len(0), arcs(0) {}
/// \brief Template copy constructor
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
StaticPath(const CPath& cpath) : arcs(0) {
/// \brief Destructor of the path
/// Destructor of the path
/// \brief Template copy assignment
/// This path can be initialized with any other path type. It just
/// makes a copy of the given path.
template <typename CPath>
StaticPath& operator=(const CPath& cpath) {
/// \brief Iterator class to iterate on the arcs of the paths
/// This class is used to iterate on the arcs of the paths
/// Of course it converts to Digraph::Arc
ArcIt(Invalid) : path(0), idx(-1) {}
/// Initializate the constructor to the first arc of path
ArcIt(const StaticPath &_path)
: path(&_path), idx(_path.empty() ? -1 : 0) {}
/// Constructor with starting point
ArcIt(const StaticPath &_path, int _idx)
: idx(_idx), path(&_path) {}
///Conversion to Digraph::Arc
operator const Arc&() const {
if (idx >= path->length()) idx = -1;
bool operator==(const ArcIt& e) const { return idx==e.idx; }
bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
bool operator<(const ArcIt& e) const { return idx<e.idx; }
/// \brief Gives back the nth arc.
/// \pre n is in the [0..length() - 1] range
const Arc& nth(int n) const {
/// \brief Initializes arc iterator to point to the nth arc.
ArcIt nthIt(int n) const {
/// \brief Gives back the length of the path.
int length() const { return len; }
/// \brief Returns true when the path is empty.
int empty() const { return len == 0; }
/// \break Erase all arc in the digraph.
/// \brief Gives back the first arc of the path.
const Arc& front() const {
/// \brief Gives back the last arc of the path.
const Arc& back() const {
template <typename CPath>
void build(const CPath& path) {
for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
template <typename CPath>
void buildRev(const CPath& path) {
for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {