00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00033
00034
00035
00036
00037
#ifndef LEMON_PATH_H
00038
#define LEMON_PATH_H
00039
00040
#include <deque>
00041
#include <vector>
00042
#include <algorithm>
00043
00044
#include <lemon/invalid.h>
00045
00046
namespace lemon {
00047
00050
00051
00063
template<
typename Graph>
00064 class DirPath {
00065
public:
00067 typedef typename Graph::Edge
GraphEdge;
00069 typedef typename Graph::Node
GraphNode;
00070
class NodeIt;
00071
class EdgeIt;
00072
00073
protected:
00074
const Graph *gr;
00075
typedef std::vector<GraphEdge> Container;
00076 Container edges;
00077
00078
public:
00079
00082 DirPath(
const Graph &_G) : gr(&_G) {}
00083
00088 DirPath(
const DirPath &P,
const NodeIt &a,
const NodeIt &b) {
00089 gr = P.
gr;
00090 edges.insert(edges.end(), P.
edges.begin()+a.
idx, P.
edges.begin()+b.
idx);
00091 }
00092
00097 DirPath(
const DirPath &P,
const EdgeIt &a,
const EdgeIt &b) {
00098 gr = P.
gr;
00099 edges.insert(edges.end(), P.
edges.begin()+a.
idx, P.
edges.begin()+b.
idx);
00100 }
00101
00103 size_t
length()
const {
return edges.size(); }
00105 bool empty()
const {
return edges.empty(); }
00106
00108 void clear() { edges.clear(); }
00109
00114 GraphNode tail()
const {
00115
return empty() ?
INVALID : gr->tail(edges[0]);
00116 }
00121 GraphNode head()
const {
00122
return empty() ?
INVALID : gr->head(edges[
length()-1]);
00123 }
00124
00129
template<
typename It>
00130 It&
first(It &i)
const {
return i=It(*
this); }
00131
00133 NodeIt&
nth(
NodeIt &i,
int n)
const {
00134
return i=
NodeIt(*
this, n);
00135 }
00136
00138 EdgeIt&
nth(
EdgeIt &i,
int n)
const {
00139
return i=
EdgeIt(*
this, n);
00140 }
00141
00144 NodeIt head(
const EdgeIt& e)
const {
00145
return NodeIt(*
this, e.
idx+1);
00146 }
00147
00150 NodeIt tail(
const EdgeIt& e)
const {
00151
return NodeIt(*
this, e.
idx);
00152 }
00153
00154
00155
00156
00166 class EdgeIt {
00167
friend class DirPath;
00168
00169
int idx;
00170
const DirPath *p;
00171
public:
00173 EdgeIt() {}
00175 EdgeIt(
Invalid) : idx(-1), p(0) {}
00177 EdgeIt(
const DirPath &_p,
int _idx = 0) :
00178 idx(_idx), p(&_p) { validate(); }
00179
00181 bool valid()
const {
return idx!=-1; }
00182
00184 operator GraphEdge ()
const {
00185
return valid() ? p->
edges[idx] :
INVALID;
00186 }
00187
00189 EdgeIt&
operator++() { ++idx; validate();
return *
this; }
00190
00192 bool operator==(
const EdgeIt& e)
const {
return idx==e.
idx; }
00194 bool operator!=(
const EdgeIt& e)
const {
return idx!=e.
idx; }
00196 bool operator<(
const EdgeIt& e)
const {
return idx<e.
idx; }
00197
00198
private:
00199
00200
00201
void validate() {
if( size_t(idx) >= p->
length() ) idx=-1; }
00202 };
00203
00213 class NodeIt {
00214
friend class DirPath;
00215
00216
int idx;
00217
const DirPath *p;
00218
public:
00220 NodeIt() {}
00222 NodeIt(
Invalid) : idx(-1), p(0) {}
00224 NodeIt(
const DirPath &_p,
int _idx = 0) :
00225 idx(_idx), p(&_p) { validate(); }
00226
00228 bool valid()
const {
return idx!=-1; }
00229
00231 operator const GraphNode& ()
const {
00232
if(idx >= p->
length())
00233
return p->
head();
00234
else if(idx >= 0)
00235
return p->
gr->tail(p->
edges[idx]);
00236
else
00237
return INVALID;
00238 }
00240 NodeIt&
operator++() { ++idx; validate();
return *
this; }
00241
00243 bool operator==(
const NodeIt& e)
const {
return idx==e.
idx; }
00245 bool operator!=(
const NodeIt& e)
const {
return idx!=e.
idx; }
00247 bool operator<(
const NodeIt& e)
const {
return idx<e.
idx; }
00248
00249
private:
00250
void validate() {
if( size_t(idx) > p->
length() ) idx=-1; }
00251 };
00252
00253
friend class Builder;
00254
00271 class Builder {
00272
DirPath &P;
00273 Container front, back;
00274
00275
public:
00278 Builder(
DirPath &_P) : P(_P) {}
00279
00281
00287 void setStartNode(
const GraphNode &) {}
00288
00290
00293 void pushFront(
const GraphEdge& e) {
00294 front.push_back(e);
00295 }
00296
00298
00301 void pushBack(
const GraphEdge& e) {
00302 back.push_back(e);
00303 }
00304
00306 void commit() {
00307
if( !front.empty() || !back.empty() ) {
00308 Container tmp;
00309 tmp.reserve(front.size()+back.size()+P.
length());
00310 tmp.insert(tmp.end(), front.rbegin(), front.rend());
00311 tmp.insert(tmp.end(), P.
edges.begin(), P.
edges.end());
00312 tmp.insert(tmp.end(), back.begin(), back.end());
00313 P.
edges.swap(tmp);
00314 front.clear();
00315 back.clear();
00316 }
00317 }
00318
00320
00323
00324 void reserveFront(size_t r) {front.reserve(r);}
00325
00327
00330
00331 void reserveBack(size_t r) {back.reserve(r);}
00332
00333
private:
00334
bool empty() {
00335
return front.empty() && back.empty() && P.
empty();
00336 }
00337
00338 GraphNode
tail()
const {
00339
if( ! front.empty() )
00340
return P.
gr->tail(front[front.size()-1]);
00341
else if( ! P.
empty() )
00342
return P.
gr->tail(P.
edges[0]);
00343
else if( ! back.empty() )
00344
return P.
gr->tail(back[0]);
00345
else
00346
return INVALID;
00347 }
00348 GraphNode
head()
const {
00349
if( ! back.empty() )
00350
return P.gr->head(back[back.size()-1]);
00351
else if( ! P.empty() )
00352
return P.gr->head(P.edges[P.length()-1]);
00353
else if( ! front.empty() )
00354
return P.gr->head(front[0]);
00355
else
00356
return INVALID;
00357 }
00358
00359 };
00360
00361 };
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00389
template<
typename Graph>
00390 class UndirPath {
00391
public:
00393 typedef typename Graph::Edge
GraphEdge;
00395 typedef typename Graph::Node
GraphNode;
00396
class NodeIt;
00397
class EdgeIt;
00398
00399
protected:
00400
const Graph *gr;
00401
typedef std::vector<GraphEdge> Container;
00402 Container edges;
00403
00404
public:
00405
00408 UndirPath(
const Graph &_G) : gr(&_G) {}
00409
00414 UndirPath(
const UndirPath &P,
const NodeIt &a,
const NodeIt &b) {
00415 gr = P.
gr;
00416 edges.insert(edges.end(), P.
edges.begin()+a.
idx, P.
edges.begin()+b.
idx);
00417 }
00418
00423 UndirPath(
const UndirPath &P,
const EdgeIt &a,
const EdgeIt &b) {
00424 gr = P.
gr;
00425 edges.insert(edges.end(), P.
edges.begin()+a.
idx, P.
edges.begin()+b.
idx);
00426 }
00427
00429 size_t
length()
const {
return edges.size(); }
00431 bool empty()
const {
return edges.empty(); }
00432
00434 void clear() { edges.clear(); }
00435
00440 GraphNode tail()
const {
00441
return empty() ?
INVALID : gr->tail(edges[0]);
00442 }
00447 GraphNode head()
const {
00448
return empty() ?
INVALID : gr->head(edges[
length()-1]);
00449 }
00450
00455
template<
typename It>
00456 It&
first(It &i)
const {
return i=It(*
this); }
00457
00459 NodeIt&
nth(
NodeIt &i,
int n)
const {
00460
return i=
NodeIt(*
this, n);
00461 }
00462
00464 EdgeIt&
nth(
EdgeIt &i,
int n)
const {
00465
return i=
EdgeIt(*
this, n);
00466 }
00467
00469
template<
typename It>
00470
static
00471 bool valid(
const It &i) {
return i.valid(); }
00472
00474
template<
typename It>
00475
static
00476 It&
next(It &e) {
00477
return ++e;
00478 }
00479
00482 NodeIt head(
const EdgeIt& e)
const {
00483
return NodeIt(*
this, e.
idx+1);
00484 }
00485
00488 NodeIt tail(
const EdgeIt& e)
const {
00489
return NodeIt(*
this, e.
idx);
00490 }
00491
00492
00493
00505 class EdgeIt {
00506
friend class UndirPath;
00507
00508
int idx;
00509
const UndirPath *p;
00510
public:
00512 EdgeIt() {}
00514 EdgeIt(
Invalid) : idx(-1), p(0) {}
00516 EdgeIt(
const UndirPath &_p,
int _idx = 0) :
00517 idx(_idx), p(&_p) { validate(); }
00518
00520 bool valid()
const {
return idx!=-1; }
00521
00523 operator GraphEdge ()
const {
00524
return valid() ? p->
edges[idx] :
INVALID;
00525 }
00527 EdgeIt&
operator++() { ++idx; validate();
return *
this; }
00528
00530 bool operator==(
const EdgeIt& e)
const {
return idx==e.
idx; }
00532 bool operator!=(
const EdgeIt& e)
const {
return idx!=e.
idx; }
00534 bool operator<(
const EdgeIt& e)
const {
return idx<e.
idx; }
00535
00536
private:
00537
00538
00539
void validate() {
if( size_t(idx) >= p->
length() ) idx=-1; }
00540 };
00541
00553 class NodeIt {
00554
friend class UndirPath;
00555
00556
int idx;
00557
const UndirPath *p;
00558
public:
00560 NodeIt() {}
00562 NodeIt(
Invalid) : idx(-1), p(0) {}
00564 NodeIt(
const UndirPath &_p,
int _idx = 0) :
00565 idx(_idx), p(&_p) { validate(); }
00566
00568 bool valid()
const {
return idx!=-1; }
00569
00571 operator const GraphNode& ()
const {
00572
if(idx >= p->
length())
00573
return p->
head();
00574
else if(idx >= 0)
00575
return p->
gr->tail(p->
edges[idx]);
00576
else
00577
return INVALID;
00578 }
00580 NodeIt&
operator++() { ++idx; validate();
return *
this; }
00581
00583 bool operator==(
const NodeIt& e)
const {
return idx==e.
idx; }
00585 bool operator!=(
const NodeIt& e)
const {
return idx!=e.
idx; }
00587 bool operator<(
const NodeIt& e)
const {
return idx<e.
idx; }
00588
00589
private:
00590
void validate() {
if( size_t(idx) > p->
length() ) idx=-1; }
00591 };
00592
00593
friend class Builder;
00594
00611 class Builder {
00612
UndirPath &P;
00613 Container front, back;
00614
00615
public:
00618 Builder(
UndirPath &_P) : P(_P) {}
00619
00621
00627 void setStartNode(
const GraphNode &) {}
00628
00630
00633 void pushFront(
const GraphEdge& e) {
00634 front.push_back(e);
00635 }
00636
00638
00641 void pushBack(
const GraphEdge& e) {
00642 back.push_back(e);
00643 }
00644
00646 void commit() {
00647
if( !(front.empty() && back.empty()) ) {
00648 Container tmp;
00649 tmp.reserve(front.size()+back.size()+P.
length());
00650 tmp.insert(tmp.end(), front.rbegin(), front.rend());
00651 tmp.insert(tmp.end(), P.
edges.begin(), P.
edges.end());
00652 tmp.insert(tmp.end(), back.begin(), back.end());
00653 P.
edges.swap(tmp);
00654 front.clear();
00655 back.clear();
00656 }
00657 }
00658
00659
00661
00664
00665 void reserveFront(size_t r) {front.reserve(r);}
00666
00668
00671
00672 void reserveBack(size_t r) {back.reserve(r);}
00673
00674
private:
00675
bool empty() {
00676
return front.empty() && back.empty() && P.
empty();
00677 }
00678
00679 GraphNode
tail()
const {
00680
if( ! front.empty() )
00681
return P.
gr->tail(front[front.size()-1]);
00682
else if( ! P.
empty() )
00683
return P.
gr->tail(P.
edges[0]);
00684
else if( ! back.empty() )
00685
return P.
gr->tail(back[0]);
00686
else
00687
return INVALID;
00688 }
00689 GraphNode
head()
const {
00690
if( ! back.empty() )
00691
return P.gr->head(back[back.size()-1]);
00692
else if( ! P.empty() )
00693
return P.gr->head(P.edges[P.length()-1]);
00694
else if( ! front.empty() )
00695
return P.gr->head(front[0]);
00696
else
00697
return INVALID;
00698 }
00699
00700 };
00701
00702 };
00703
00704
00706
00707 }
00708
00709
#endif // LEMON_PATH_H