00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00033
00034
00035
00036
00037
00038
00039 #ifndef LEMON_PATH_H
00040 #define LEMON_PATH_H
00041
00042 #include <deque>
00043 #include <vector>
00044 #include <algorithm>
00045
00046 #include <lemon/invalid.h>
00047
00048 namespace lemon {
00049
00052
00053
00065 template<typename Graph>
00066 class DirPath {
00067 public:
00069 typedef typename Graph::Edge GraphEdge;
00071 typedef typename Graph::Node GraphNode;
00072 class NodeIt;
00073 class EdgeIt;
00074
00075 protected:
00076 const Graph *gr;
00077 typedef std::vector<GraphEdge> Container;
00078 Container edges;
00079
00080 public:
00081
00084 DirPath(const Graph &_G) : gr(&_G) {}
00085
00090 DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
00091 gr = P.gr;
00092 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00093 }
00094
00099 DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
00100 gr = P.gr;
00101 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00102 }
00103
00105 int length() const { return edges.size(); }
00107 bool empty() const { return edges.empty(); }
00108
00110 void clear() { edges.clear(); }
00111
00116 GraphNode source() const {
00117 return empty() ? INVALID : gr->source(edges[0]);
00118 }
00123 GraphNode target() const {
00124 return empty() ? INVALID : gr->target(edges[length()-1]);
00125 }
00126
00131 template<typename It>
00132 It& first(It &i) const { return i=It(*this); }
00133
00135 NodeIt& nth(NodeIt &i, int n) const {
00136 return i=NodeIt(*this, n);
00137 }
00138
00140 EdgeIt& nth(EdgeIt &i, int n) const {
00141 return i=EdgeIt(*this, n);
00142 }
00143
00146 NodeIt target(const EdgeIt& e) const {
00147 return NodeIt(*this, e.idx+1);
00148 }
00149
00152 NodeIt source(const EdgeIt& e) const {
00153 return NodeIt(*this, e.idx);
00154 }
00155
00156
00157
00158
00167 class EdgeIt {
00168 friend class DirPath;
00169
00170 int idx;
00171 const DirPath *p;
00172 public:
00174 EdgeIt() {}
00176 EdgeIt(Invalid) : idx(-1), p(0) {}
00178 EdgeIt(const DirPath &_p, int _idx = 0) :
00179 idx(_idx), p(&_p) { validate(); }
00180
00182 bool valid() const { return idx!=-1; }
00183
00185 operator GraphEdge () const {
00186 return valid() ? p->edges[idx] : INVALID;
00187 }
00188
00190 EdgeIt& operator++() { ++idx; validate(); return *this; }
00191
00193 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
00195 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
00197 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
00198
00199 private:
00200 void validate() { if(idx >= p->length() ) idx=-1; }
00201 };
00202
00211 class NodeIt {
00212 friend class DirPath;
00213
00214 int idx;
00215 const DirPath *p;
00216 public:
00218 NodeIt() {}
00220 NodeIt(Invalid) : idx(-1), p(0) {}
00222 NodeIt(const DirPath &_p, int _idx = 0) :
00223 idx(_idx), p(&_p) { validate(); }
00224
00226 bool valid() const { return idx!=-1; }
00227
00229 operator const GraphNode& () const {
00230 if(idx >= p->length())
00231 return p->target();
00232 else if(idx >= 0)
00233 return p->gr->source(p->edges[idx]);
00234 else
00235 return INVALID;
00236 }
00238 NodeIt& operator++() { ++idx; validate(); return *this; }
00239
00241 bool operator==(const NodeIt& e) const { return idx==e.idx; }
00243 bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
00245 bool operator<(const NodeIt& e) const { return idx<e.idx; }
00246
00247 private:
00248 void validate() { if(idx > p->length() ) idx=-1; }
00249 };
00250
00251 friend class Builder;
00252
00268 class Builder {
00269 DirPath &P;
00270 Container front, back;
00271
00272 public:
00275 Builder(DirPath &_p) : P(_p) {}
00276
00278
00284 void setStartNode(const GraphNode &) {}
00285
00287
00290 void pushFront(const GraphEdge& e) {
00291 front.push_back(e);
00292 }
00293
00295
00298 void pushBack(const GraphEdge& e) {
00299 back.push_back(e);
00300 }
00301
00303 void commit() {
00304 if( !front.empty() || !back.empty() ) {
00305 Container tmp;
00306 tmp.reserve(front.size()+back.size()+P.length());
00307 tmp.insert(tmp.end(), front.rbegin(), front.rend());
00308 tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
00309 tmp.insert(tmp.end(), back.begin(), back.end());
00310 P.edges.swap(tmp);
00311 front.clear();
00312 back.clear();
00313 }
00314 }
00315
00317
00320
00321 void reserveFront(size_t r) {front.reserve(r);}
00322
00324
00327
00328 void reserveBack(size_t r) {back.reserve(r);}
00329
00330 private:
00331 bool empty() {
00332 return front.empty() && back.empty() && P.empty();
00333 }
00334
00335 GraphNode source() const {
00336 if( ! front.empty() )
00337 return P.gr->source(front[front.size()-1]);
00338 else if( ! P.empty() )
00339 return P.gr->source(P.edges[0]);
00340 else if( ! back.empty() )
00341 return P.gr->source(back[0]);
00342 else
00343 return INVALID;
00344 }
00345 GraphNode target() const {
00346 if( ! back.empty() )
00347 return P.gr->target(back[back.size()-1]);
00348 else if( ! P.empty() )
00349 return P.gr->target(P.edges[P.length()-1]);
00350 else if( ! front.empty() )
00351 return P.gr->target(front[0]);
00352 else
00353 return INVALID;
00354 }
00355
00356 };
00357
00358 };
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00386 template<typename Graph>
00387 class UndirPath {
00388 public:
00390 typedef typename Graph::Edge GraphEdge;
00392 typedef typename Graph::Node GraphNode;
00393 class NodeIt;
00394 class EdgeIt;
00395
00396 protected:
00397 const Graph *gr;
00398 typedef std::vector<GraphEdge> Container;
00399 Container edges;
00400
00401 public:
00402
00405 UndirPath(const Graph &_G) : gr(&_G) {}
00406
00411 UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
00412 gr = P.gr;
00413 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00414 }
00415
00420 UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
00421 gr = P.gr;
00422 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
00423 }
00424
00426 size_t length() const { return edges.size(); }
00428 bool empty() const { return edges.empty(); }
00429
00431 void clear() { edges.clear(); }
00432
00437 GraphNode source() const {
00438 return empty() ? INVALID : gr->source(edges[0]);
00439 }
00444 GraphNode target() const {
00445 return empty() ? INVALID : gr->target(edges[length()-1]);
00446 }
00447
00452 template<typename It>
00453 It& first(It &i) const { return i=It(*this); }
00454
00456 NodeIt& nth(NodeIt &i, int n) const {
00457 return i=NodeIt(*this, n);
00458 }
00459
00461 EdgeIt& nth(EdgeIt &i, int n) const {
00462 return i=EdgeIt(*this, n);
00463 }
00464
00466 template<typename It>
00467 static
00468 bool valid(const It &i) { return i.valid(); }
00469
00471 template<typename It>
00472 static
00473 It& next(It &e) {
00474 return ++e;
00475 }
00476
00479 NodeIt target(const EdgeIt& e) const {
00480 return NodeIt(*this, e.idx+1);
00481 }
00482
00485 NodeIt source(const EdgeIt& e) const {
00486 return NodeIt(*this, e.idx);
00487 }
00488
00489
00490
00501 class EdgeIt {
00502 friend class UndirPath;
00503
00504 int idx;
00505 const UndirPath *p;
00506 public:
00508 EdgeIt() {}
00510 EdgeIt(Invalid) : idx(-1), p(0) {}
00512 EdgeIt(const UndirPath &_p, int _idx = 0) :
00513 idx(_idx), p(&_p) { validate(); }
00514
00516 bool valid() const { return idx!=-1; }
00517
00519 operator GraphEdge () const {
00520 return valid() ? p->edges[idx] : INVALID;
00521 }
00523 EdgeIt& operator++() { ++idx; validate(); return *this; }
00524
00526 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
00528 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
00530 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
00531
00532 private:
00533
00534
00535 void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
00536 };
00537
00548 class NodeIt {
00549 friend class UndirPath;
00550
00551 int idx;
00552 const UndirPath *p;
00553 public:
00555 NodeIt() {}
00557 NodeIt(Invalid) : idx(-1), p(0) {}
00559 NodeIt(const UndirPath &_p, int _idx = 0) :
00560 idx(_idx), p(&_p) { validate(); }
00561
00563 bool valid() const { return idx!=-1; }
00564
00566 operator const GraphNode& () const {
00567 if(idx >= p->length())
00568 return p->target();
00569 else if(idx >= 0)
00570 return p->gr->source(p->edges[idx]);
00571 else
00572 return INVALID;
00573 }
00575 NodeIt& operator++() { ++idx; validate(); return *this; }
00576
00578 bool operator==(const NodeIt& e) const { return idx==e.idx; }
00580 bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
00582 bool operator<(const NodeIt& e) const { return idx<e.idx; }
00583
00584 private:
00585 void validate() { if( size_t(idx) > p->length() ) idx=-1; }
00586 };
00587
00588 friend class Builder;
00589
00605 class Builder {
00606 UndirPath &P;
00607 Container front, back;
00608
00609 public:
00612 Builder(UndirPath &_p) : P(_p) {}
00613
00615
00621 void setStartNode(const GraphNode &) {}
00622
00624
00627 void pushFront(const GraphEdge& e) {
00628 front.push_back(e);
00629 }
00630
00632
00635 void pushBack(const GraphEdge& e) {
00636 back.push_back(e);
00637 }
00638
00640 void commit() {
00641 if( !(front.empty() && back.empty()) ) {
00642 Container tmp;
00643 tmp.reserve(front.size()+back.size()+P.length());
00644 tmp.insert(tmp.end(), front.rbegin(), front.rend());
00645 tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
00646 tmp.insert(tmp.end(), back.begin(), back.end());
00647 P.edges.swap(tmp);
00648 front.clear();
00649 back.clear();
00650 }
00651 }
00652
00653
00655
00658
00659 void reserveFront(size_t r) {front.reserve(r);}
00660
00662
00665
00666 void reserveBack(size_t r) {back.reserve(r);}
00667
00668 private:
00669 bool empty() {
00670 return front.empty() && back.empty() && P.empty();
00671 }
00672
00673 GraphNode source() const {
00674 if( ! front.empty() )
00675 return P.gr->source(front[front.size()-1]);
00676 else if( ! P.empty() )
00677 return P.gr->source(P.edges[0]);
00678 else if( ! back.empty() )
00679 return P.gr->source(back[0]);
00680 else
00681 return INVALID;
00682 }
00683 GraphNode target() const {
00684 if( ! back.empty() )
00685 return P.gr->target(back[back.size()-1]);
00686 else if( ! P.empty() )
00687 return P.gr->target(P.edges[P.length()-1]);
00688 else if( ! front.empty() )
00689 return P.gr->target(front[0]);
00690 else
00691 return INVALID;
00692 }
00693
00694 };
00695
00696 };
00697
00698
00700
00701 }
00702
00703 #endif // LEMON_PATH_H