| ... | ... |
@@ -14,143 +14,146 @@ |
| 14 | 14 |
* express or implied, and with no claim as to its suitability for any |
| 15 | 15 |
* purpose. |
| 16 | 16 |
* |
| 17 | 17 |
*/ |
| 18 | 18 |
|
| 19 | 19 |
#ifndef LEMON_BITS_BASE_EXTENDER_H |
| 20 | 20 |
#define LEMON_BITS_BASE_EXTENDER_H |
| 21 | 21 |
|
| 22 | 22 |
#include <lemon/core.h> |
| 23 | 23 |
#include <lemon/error.h> |
| 24 | 24 |
|
| 25 | 25 |
#include <lemon/bits/map_extender.h> |
| 26 | 26 |
#include <lemon/bits/default_map.h> |
| 27 | 27 |
|
| 28 | 28 |
#include <lemon/concept_check.h> |
| 29 | 29 |
#include <lemon/concepts/maps.h> |
| 30 | 30 |
|
| 31 | 31 |
///\ingroup digraphbits |
| 32 | 32 |
///\file |
| 33 | 33 |
///\brief Extenders for the digraph types |
| 34 | 34 |
namespace lemon {
|
| 35 | 35 |
|
| 36 | 36 |
/// \ingroup digraphbits |
| 37 | 37 |
/// |
| 38 | 38 |
/// \brief BaseDigraph to BaseGraph extender |
| 39 | 39 |
template <typename Base> |
| 40 | 40 |
class UndirDigraphExtender : public Base {
|
| 41 | 41 |
|
| 42 | 42 |
public: |
| 43 | 43 |
|
| 44 | 44 |
typedef Base Parent; |
| 45 | 45 |
typedef typename Parent::Arc Edge; |
| 46 | 46 |
typedef typename Parent::Node Node; |
| 47 | 47 |
|
| 48 | 48 |
typedef True UndirectedTag; |
| 49 | 49 |
|
| 50 | 50 |
class Arc : public Edge {
|
| 51 | 51 |
friend class UndirDigraphExtender; |
| 52 | 52 |
|
| 53 | 53 |
protected: |
| 54 | 54 |
bool forward; |
| 55 | 55 |
|
| 56 | 56 |
Arc(const Edge &ue, bool _forward) : |
| 57 | 57 |
Edge(ue), forward(_forward) {}
|
| 58 | 58 |
|
| 59 | 59 |
public: |
| 60 | 60 |
Arc() {}
|
| 61 | 61 |
|
| 62 |
// |
|
| 62 |
// Invalid arc constructor |
|
| 63 | 63 |
Arc(Invalid i) : Edge(i), forward(true) {}
|
| 64 | 64 |
|
| 65 | 65 |
bool operator==(const Arc &that) const {
|
| 66 | 66 |
return forward==that.forward && Edge(*this)==Edge(that); |
| 67 | 67 |
} |
| 68 | 68 |
bool operator!=(const Arc &that) const {
|
| 69 | 69 |
return forward!=that.forward || Edge(*this)!=Edge(that); |
| 70 | 70 |
} |
| 71 | 71 |
bool operator<(const Arc &that) const {
|
| 72 | 72 |
return forward<that.forward || |
| 73 | 73 |
(!(that.forward<forward) && Edge(*this)<Edge(that)); |
| 74 | 74 |
} |
| 75 | 75 |
}; |
| 76 | 76 |
|
| 77 |
/// First node of the edge |
|
| 78 |
Node u(const Edge &e) const {
|
|
| 79 |
return Parent::source(e); |
|
| 80 |
} |
|
| 77 | 81 |
|
| 78 |
|
|
| 79 |
using Parent::source; |
|
| 80 |
|
|
| 81 |
/// Source of the given Arc. |
|
| 82 |
/// Source of the given arc |
|
| 82 | 83 |
Node source(const Arc &e) const {
|
| 83 | 84 |
return e.forward ? Parent::source(e) : Parent::target(e); |
| 84 | 85 |
} |
| 85 | 86 |
|
| 86 |
|
|
| 87 |
/// Second node of the edge |
|
| 88 |
Node v(const Edge &e) const {
|
|
| 89 |
return Parent::target(e); |
|
| 90 |
} |
|
| 87 | 91 |
|
| 88 |
/// Target of the given |
|
| 92 |
/// Target of the given arc |
|
| 89 | 93 |
Node target(const Arc &e) const {
|
| 90 | 94 |
return e.forward ? Parent::target(e) : Parent::source(e); |
| 91 | 95 |
} |
| 92 | 96 |
|
| 93 | 97 |
/// \brief Directed arc from an edge. |
| 94 | 98 |
/// |
| 95 |
/// Returns a directed arc corresponding to the specified Edge. |
|
| 96 |
/// If the given bool is true the given edge and the |
|
| 97 |
/// returned arc have the same source node. |
|
| 98 |
static Arc direct(const Edge &ue, bool d) {
|
|
| 99 |
|
|
| 99 |
/// Returns a directed arc corresponding to the specified edge. |
|
| 100 |
/// If the given bool is true, the first node of the given edge and |
|
| 101 |
/// the source node of the returned arc are the same. |
|
| 102 |
static Arc direct(const Edge &e, bool d) {
|
|
| 103 |
return Arc(e, d); |
|
| 100 | 104 |
} |
| 101 | 105 |
|
| 102 |
/// Returns whether the given directed arc is same orientation as the |
|
| 103 |
/// corresponding edge. |
|
| 106 |
/// Returns whether the given directed arc has the same orientation |
|
| 107 |
/// as the corresponding edge. |
|
| 104 | 108 |
/// |
| 105 | 109 |
/// \todo reference to the corresponding point of the undirected digraph |
| 106 | 110 |
/// concept. "What does the direction of an edge mean?" |
| 107 |
static bool direction(const Arc &e) { return e.forward; }
|
|
| 108 |
|
|
| 111 |
static bool direction(const Arc &a) { return a.forward; }
|
|
| 109 | 112 |
|
| 110 | 113 |
using Parent::first; |
| 111 | 114 |
using Parent::next; |
| 112 | 115 |
|
| 113 | 116 |
void first(Arc &e) const {
|
| 114 | 117 |
Parent::first(e); |
| 115 | 118 |
e.forward=true; |
| 116 | 119 |
} |
| 117 | 120 |
|
| 118 | 121 |
void next(Arc &e) const {
|
| 119 | 122 |
if( e.forward ) {
|
| 120 | 123 |
e.forward = false; |
| 121 | 124 |
} |
| 122 | 125 |
else {
|
| 123 | 126 |
Parent::next(e); |
| 124 | 127 |
e.forward = true; |
| 125 | 128 |
} |
| 126 | 129 |
} |
| 127 | 130 |
|
| 128 | 131 |
void firstOut(Arc &e, const Node &n) const {
|
| 129 | 132 |
Parent::firstIn(e,n); |
| 130 | 133 |
if( Edge(e) != INVALID ) {
|
| 131 | 134 |
e.forward = false; |
| 132 | 135 |
} |
| 133 | 136 |
else {
|
| 134 | 137 |
Parent::firstOut(e,n); |
| 135 | 138 |
e.forward = true; |
| 136 | 139 |
} |
| 137 | 140 |
} |
| 138 | 141 |
void nextOut(Arc &e) const {
|
| 139 | 142 |
if( ! e.forward ) {
|
| 140 | 143 |
Node n = Parent::target(e); |
| 141 | 144 |
Parent::nextIn(e); |
| 142 | 145 |
if( Edge(e) == INVALID ) {
|
| 143 | 146 |
Parent::firstOut(e, n); |
| 144 | 147 |
e.forward = true; |
| 145 | 148 |
} |
| 146 | 149 |
} |
| 147 | 150 |
else {
|
| 148 | 151 |
Parent::nextOut(e); |
| 149 | 152 |
} |
| 150 | 153 |
} |
| 151 | 154 |
|
| 152 | 155 |
void firstIn(Arc &e, const Node &n) const {
|
| 153 | 156 |
Parent::firstOut(e,n); |
| 154 | 157 |
if( Edge(e) != INVALID ) {
|
| 155 | 158 |
e.forward = false; |
| 156 | 159 |
} |
| ... | ... |
@@ -184,97 +187,96 @@ |
| 184 | 187 |
void nextInc(Edge &e, bool &d) const {
|
| 185 | 188 |
if (d) {
|
| 186 | 189 |
Node s = Parent::source(e); |
| 187 | 190 |
Parent::nextOut(e); |
| 188 | 191 |
if (e != INVALID) return; |
| 189 | 192 |
d = false; |
| 190 | 193 |
Parent::firstIn(e, s); |
| 191 | 194 |
} else {
|
| 192 | 195 |
Parent::nextIn(e); |
| 193 | 196 |
} |
| 194 | 197 |
} |
| 195 | 198 |
|
| 196 | 199 |
Node nodeFromId(int ix) const {
|
| 197 | 200 |
return Parent::nodeFromId(ix); |
| 198 | 201 |
} |
| 199 | 202 |
|
| 200 | 203 |
Arc arcFromId(int ix) const {
|
| 201 | 204 |
return direct(Parent::arcFromId(ix >> 1), bool(ix & 1)); |
| 202 | 205 |
} |
| 203 | 206 |
|
| 204 | 207 |
Edge edgeFromId(int ix) const {
|
| 205 | 208 |
return Parent::arcFromId(ix); |
| 206 | 209 |
} |
| 207 | 210 |
|
| 208 | 211 |
int id(const Node &n) const {
|
| 209 | 212 |
return Parent::id(n); |
| 210 | 213 |
} |
| 211 | 214 |
|
| 212 | 215 |
int id(const Edge &e) const {
|
| 213 | 216 |
return Parent::id(e); |
| 214 | 217 |
} |
| 215 | 218 |
|
| 216 | 219 |
int id(const Arc &e) const {
|
| 217 | 220 |
return 2 * Parent::id(e) + int(e.forward); |
| 218 | 221 |
} |
| 219 | 222 |
|
| 220 | 223 |
int maxNodeId() const {
|
| 221 | 224 |
return Parent::maxNodeId(); |
| 222 | 225 |
} |
| 223 | 226 |
|
| 224 | 227 |
int maxArcId() const {
|
| 225 | 228 |
return 2 * Parent::maxArcId() + 1; |
| 226 | 229 |
} |
| 227 | 230 |
|
| 228 | 231 |
int maxEdgeId() const {
|
| 229 | 232 |
return Parent::maxArcId(); |
| 230 | 233 |
} |
| 231 | 234 |
|
| 232 |
|
|
| 233 | 235 |
int arcNum() const {
|
| 234 | 236 |
return 2 * Parent::arcNum(); |
| 235 | 237 |
} |
| 236 | 238 |
|
| 237 | 239 |
int edgeNum() const {
|
| 238 | 240 |
return Parent::arcNum(); |
| 239 | 241 |
} |
| 240 | 242 |
|
| 241 | 243 |
Arc findArc(Node s, Node t, Arc p = INVALID) const {
|
| 242 | 244 |
if (p == INVALID) {
|
| 243 | 245 |
Edge arc = Parent::findArc(s, t); |
| 244 | 246 |
if (arc != INVALID) return direct(arc, true); |
| 245 | 247 |
arc = Parent::findArc(t, s); |
| 246 | 248 |
if (arc != INVALID) return direct(arc, false); |
| 247 | 249 |
} else if (direction(p)) {
|
| 248 | 250 |
Edge arc = Parent::findArc(s, t, p); |
| 249 | 251 |
if (arc != INVALID) return direct(arc, true); |
| 250 | 252 |
arc = Parent::findArc(t, s); |
| 251 | 253 |
if (arc != INVALID) return direct(arc, false); |
| 252 | 254 |
} else {
|
| 253 | 255 |
Edge arc = Parent::findArc(t, s, p); |
| 254 | 256 |
if (arc != INVALID) return direct(arc, false); |
| 255 | 257 |
} |
| 256 | 258 |
return INVALID; |
| 257 | 259 |
} |
| 258 | 260 |
|
| 259 | 261 |
Edge findEdge(Node s, Node t, Edge p = INVALID) const {
|
| 260 | 262 |
if (s != t) {
|
| 261 | 263 |
if (p == INVALID) {
|
| 262 | 264 |
Edge arc = Parent::findArc(s, t); |
| 263 | 265 |
if (arc != INVALID) return arc; |
| 264 | 266 |
arc = Parent::findArc(t, s); |
| 265 | 267 |
if (arc != INVALID) return arc; |
| 266 | 268 |
} else if (Parent::s(p) == s) {
|
| 267 | 269 |
Edge arc = Parent::findArc(s, t, p); |
| 268 | 270 |
if (arc != INVALID) return arc; |
| 269 | 271 |
arc = Parent::findArc(t, s); |
| 270 | 272 |
if (arc != INVALID) return arc; |
| 271 | 273 |
} else {
|
| 272 | 274 |
Edge arc = Parent::findArc(t, s, p); |
| 273 | 275 |
if (arc != INVALID) return arc; |
| 274 | 276 |
} |
| 275 | 277 |
} else {
|
| 276 | 278 |
return Parent::findArc(s, t, p); |
| 277 | 279 |
} |
| 278 | 280 |
return INVALID; |
| 279 | 281 |
} |
| 280 | 282 |
}; |
0 comments (0 inline)