gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Modify the implementation of ListDigraph::ArcIt (#311) The new implementation is based on out-arc iteration (like ListGraph::ArcIt) instead of in-arc iteration to make it consistent with the documentation.
0 1 0
default
1 file changed with 7 insertions and 7 deletions:
↑ Collapse diff ↑
Show white space 1536 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
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_LIST_GRAPH_H
20 20
#define LEMON_LIST_GRAPH_H
21 21

	
22 22
///\ingroup graphs
23 23
///\file
24 24
///\brief ListDigraph, ListGraph classes.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/error.h>
28 28
#include <lemon/bits/graph_extender.h>
29 29

	
30 30
#include <vector>
31 31
#include <list>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  class ListDigraphBase {
36 36

	
37 37
  protected:
38 38
    struct NodeT {
39 39
      int first_in, first_out;
40 40
      int prev, next;
41 41
    };
42 42

	
43 43
    struct ArcT {
44 44
      int target, source;
45 45
      int prev_in, prev_out;
46 46
      int next_in, next_out;
47 47
    };
48 48

	
49 49
    std::vector<NodeT> nodes;
50 50

	
51 51
    int first_node;
52 52

	
53 53
    int first_free_node;
54 54

	
55 55
    std::vector<ArcT> arcs;
56 56

	
57 57
    int first_free_arc;
58 58

	
59 59
  public:
60 60

	
61 61
    typedef ListDigraphBase Digraph;
62 62

	
63 63
    class Node {
64 64
      friend class ListDigraphBase;
65 65
    protected:
66 66

	
67 67
      int id;
68 68
      explicit Node(int pid) { id = pid;}
69 69

	
70 70
    public:
71 71
      Node() {}
72 72
      Node (Invalid) { id = -1; }
73 73
      bool operator==(const Node& node) const {return id == node.id;}
74 74
      bool operator!=(const Node& node) const {return id != node.id;}
75 75
      bool operator<(const Node& node) const {return id < node.id;}
76 76
    };
77 77

	
78 78
    class Arc {
79 79
      friend class ListDigraphBase;
80 80
    protected:
81 81

	
82 82
      int id;
83 83
      explicit Arc(int pid) { id = pid;}
84 84

	
85 85
    public:
86 86
      Arc() {}
87 87
      Arc (Invalid) { id = -1; }
88 88
      bool operator==(const Arc& arc) const {return id == arc.id;}
89 89
      bool operator!=(const Arc& arc) const {return id != arc.id;}
90 90
      bool operator<(const Arc& arc) const {return id < arc.id;}
91 91
    };
92 92

	
93 93

	
94 94

	
95 95
    ListDigraphBase()
96 96
      : nodes(), first_node(-1),
97 97
        first_free_node(-1), arcs(), first_free_arc(-1) {}
98 98

	
99 99

	
100 100
    int maxNodeId() const { return nodes.size()-1; }
101 101
    int maxArcId() const { return arcs.size()-1; }
102 102

	
103 103
    Node source(Arc e) const { return Node(arcs[e.id].source); }
104 104
    Node target(Arc e) const { return Node(arcs[e.id].target); }
105 105

	
106 106

	
107 107
    void first(Node& node) const {
108 108
      node.id = first_node;
109 109
    }
110 110

	
111 111
    void next(Node& node) const {
112 112
      node.id = nodes[node.id].next;
113 113
    }
114 114

	
115 115

	
116 116
    void first(Arc& arc) const {
117 117
      int n;
118 118
      for(n = first_node;
119
          n!=-1 && nodes[n].first_in == -1;
119
          n != -1 && nodes[n].first_out == -1;
120 120
          n = nodes[n].next) {}
121
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
121
      arc.id = (n == -1) ? -1 : nodes[n].first_out;
122 122
    }
123 123

	
124 124
    void next(Arc& arc) const {
125
      if (arcs[arc.id].next_in != -1) {
126
        arc.id = arcs[arc.id].next_in;
125
      if (arcs[arc.id].next_out != -1) {
126
        arc.id = arcs[arc.id].next_out;
127 127
      } else {
128 128
        int n;
129
        for(n = nodes[arcs[arc.id].target].next;
130
            n!=-1 && nodes[n].first_in == -1;
129
        for(n = nodes[arcs[arc.id].source].next;
130
            n != -1 && nodes[n].first_out == -1;
131 131
            n = nodes[n].next) {}
132
        arc.id = (n == -1) ? -1 : nodes[n].first_in;
132
        arc.id = (n == -1) ? -1 : nodes[n].first_out;
133 133
      }
134 134
    }
135 135

	
136 136
    void firstOut(Arc &e, const Node& v) const {
137 137
      e.id = nodes[v.id].first_out;
138 138
    }
139 139
    void nextOut(Arc &e) const {
140 140
      e.id=arcs[e.id].next_out;
141 141
    }
142 142

	
143 143
    void firstIn(Arc &e, const Node& v) const {
144 144
      e.id = nodes[v.id].first_in;
145 145
    }
146 146
    void nextIn(Arc &e) const {
147 147
      e.id=arcs[e.id].next_in;
148 148
    }
149 149

	
150 150

	
151 151
    static int id(Node v) { return v.id; }
152 152
    static int id(Arc e) { return e.id; }
153 153

	
154 154
    static Node nodeFromId(int id) { return Node(id);}
155 155
    static Arc arcFromId(int id) { return Arc(id);}
156 156

	
157 157
    bool valid(Node n) const {
158 158
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
159 159
        nodes[n.id].prev != -2;
160 160
    }
161 161

	
162 162
    bool valid(Arc a) const {
163 163
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
164 164
        arcs[a.id].prev_in != -2;
165 165
    }
166 166

	
167 167
    Node addNode() {
168 168
      int n;
169 169

	
170 170
      if(first_free_node==-1) {
171 171
        n = nodes.size();
172 172
        nodes.push_back(NodeT());
173 173
      } else {
174 174
        n = first_free_node;
175 175
        first_free_node = nodes[n].next;
176 176
      }
177 177

	
178 178
      nodes[n].next = first_node;
179 179
      if(first_node != -1) nodes[first_node].prev = n;
180 180
      first_node = n;
181 181
      nodes[n].prev = -1;
182 182

	
183 183
      nodes[n].first_in = nodes[n].first_out = -1;
184 184

	
185 185
      return Node(n);
186 186
    }
187 187

	
188 188
    Arc addArc(Node u, Node v) {
189 189
      int n;
190 190

	
191 191
      if (first_free_arc == -1) {
192 192
        n = arcs.size();
193 193
        arcs.push_back(ArcT());
194 194
      } else {
195 195
        n = first_free_arc;
196 196
        first_free_arc = arcs[n].next_in;
197 197
      }
198 198

	
199 199
      arcs[n].source = u.id;
200 200
      arcs[n].target = v.id;
201 201

	
202 202
      arcs[n].next_out = nodes[u.id].first_out;
203 203
      if(nodes[u.id].first_out != -1) {
204 204
        arcs[nodes[u.id].first_out].prev_out = n;
205 205
      }
206 206

	
207 207
      arcs[n].next_in = nodes[v.id].first_in;
208 208
      if(nodes[v.id].first_in != -1) {
209 209
        arcs[nodes[v.id].first_in].prev_in = n;
210 210
      }
211 211

	
212 212
      arcs[n].prev_in = arcs[n].prev_out = -1;
213 213

	
214 214
      nodes[u.id].first_out = nodes[v.id].first_in = n;
215 215

	
216 216
      return Arc(n);
217 217
    }
218 218

	
219 219
    void erase(const Node& node) {
220 220
      int n = node.id;
221 221

	
222 222
      if(nodes[n].next != -1) {
223 223
        nodes[nodes[n].next].prev = nodes[n].prev;
224 224
      }
225 225

	
226 226
      if(nodes[n].prev != -1) {
227 227
        nodes[nodes[n].prev].next = nodes[n].next;
228 228
      } else {
229 229
        first_node = nodes[n].next;
230 230
      }
231 231

	
232 232
      nodes[n].next = first_free_node;
233 233
      first_free_node = n;
234 234
      nodes[n].prev = -2;
235 235

	
236 236
    }
237 237

	
238 238
    void erase(const Arc& arc) {
239 239
      int n = arc.id;
240 240

	
241 241
      if(arcs[n].next_in!=-1) {
242 242
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
243 243
      }
244 244

	
245 245
      if(arcs[n].prev_in!=-1) {
246 246
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
247 247
      } else {
248 248
        nodes[arcs[n].target].first_in = arcs[n].next_in;
249 249
      }
250 250

	
251 251

	
252 252
      if(arcs[n].next_out!=-1) {
253 253
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
254 254
      }
255 255

	
256 256
      if(arcs[n].prev_out!=-1) {
257 257
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
258 258
      } else {
259 259
        nodes[arcs[n].source].first_out = arcs[n].next_out;
260 260
      }
261 261

	
262 262
      arcs[n].next_in = first_free_arc;
263 263
      first_free_arc = n;
264 264
      arcs[n].prev_in = -2;
265 265
    }
266 266

	
267 267
    void clear() {
268 268
      arcs.clear();
269 269
      nodes.clear();
270 270
      first_node = first_free_node = first_free_arc = -1;
271 271
    }
272 272

	
273 273
  protected:
274 274
    void changeTarget(Arc e, Node n)
275 275
    {
276 276
      if(arcs[e.id].next_in != -1)
277 277
        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
278 278
      if(arcs[e.id].prev_in != -1)
279 279
        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
280 280
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
281 281
      if (nodes[n.id].first_in != -1) {
282 282
        arcs[nodes[n.id].first_in].prev_in = e.id;
283 283
      }
284 284
      arcs[e.id].target = n.id;
285 285
      arcs[e.id].prev_in = -1;
286 286
      arcs[e.id].next_in = nodes[n.id].first_in;
287 287
      nodes[n.id].first_in = e.id;
288 288
    }
289 289
    void changeSource(Arc e, Node n)
290 290
    {
291 291
      if(arcs[e.id].next_out != -1)
292 292
        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
293 293
      if(arcs[e.id].prev_out != -1)
294 294
        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
295 295
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
296 296
      if (nodes[n.id].first_out != -1) {
297 297
        arcs[nodes[n.id].first_out].prev_out = e.id;
298 298
      }
299 299
      arcs[e.id].source = n.id;
300 300
      arcs[e.id].prev_out = -1;
301 301
      arcs[e.id].next_out = nodes[n.id].first_out;
302 302
      nodes[n.id].first_out = e.id;
303 303
    }
304 304

	
305 305
  };
306 306

	
307 307
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
308 308

	
309 309
  /// \addtogroup graphs
310 310
  /// @{
311 311

	
312 312
  ///A general directed graph structure.
313 313

	
314 314
  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
315 315
  ///implementation based on static linked lists that are stored in
316 316
  ///\c std::vector structures.
317 317
  ///
318 318
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
319 319
  ///also provides several useful additional functionalities.
320 320
  ///Most of the member functions and nested classes are documented
321 321
  ///only in the concept class.
322 322
  ///
323 323
  ///\sa concepts::Digraph
324 324

	
325 325
  class ListDigraph : public ExtendedListDigraphBase {
326 326
    typedef ExtendedListDigraphBase Parent;
327 327

	
328 328
  private:
329 329
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
330 330

	
331 331
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
332 332
    ///
333 333
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
334 334
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
335 335
    ///Use copyDigraph() instead.
336 336

	
337 337
    ///Assignment of ListDigraph to another one is \e not allowed.
338 338
    ///Use copyDigraph() instead.
339 339
    void operator=(const ListDigraph &) {}
340 340
  public:
341 341

	
342 342
    /// Constructor
343 343

	
344 344
    /// Constructor.
345 345
    ///
346 346
    ListDigraph() {}
347 347

	
348 348
    ///Add a new node to the digraph.
349 349

	
350 350
    ///Add a new node to the digraph.
351 351
    ///\return The new node.
352 352
    Node addNode() { return Parent::addNode(); }
353 353

	
354 354
    ///Add a new arc to the digraph.
355 355

	
356 356
    ///Add a new arc to the digraph with source node \c s
357 357
    ///and target node \c t.
358 358
    ///\return The new arc.
359 359
    Arc addArc(const Node& s, const Node& t) {
360 360
      return Parent::addArc(s, t);
361 361
    }
362 362

	
363 363
    ///\brief Erase a node from the digraph.
364 364
    ///
365 365
    ///Erase a node from the digraph.
366 366
    ///
367 367
    void erase(const Node& n) { Parent::erase(n); }
368 368

	
369 369
    ///\brief Erase an arc from the digraph.
370 370
    ///
371 371
    ///Erase an arc from the digraph.
372 372
    ///
373 373
    void erase(const Arc& a) { Parent::erase(a); }
374 374

	
375 375
    /// Node validity check
376 376

	
377 377
    /// This function gives back true if the given node is valid,
378 378
    /// ie. it is a real node of the graph.
379 379
    ///
380 380
    /// \warning A Node pointing to a removed item
381 381
    /// could become valid again later if new nodes are
382 382
    /// added to the graph.
383 383
    bool valid(Node n) const { return Parent::valid(n); }
384 384

	
385 385
    /// Arc validity check
386 386

	
387 387
    /// This function gives back true if the given arc is valid,
388 388
    /// ie. it is a real arc of the graph.
389 389
    ///
390 390
    /// \warning An Arc pointing to a removed item
391 391
    /// could become valid again later if new nodes are
392 392
    /// added to the graph.
393 393
    bool valid(Arc a) const { return Parent::valid(a); }
394 394

	
395 395
    /// Change the target of \c a to \c n
396 396

	
397 397
    /// Change the target of \c a to \c n
398 398
    ///
399 399
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
400 400
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
401 401
    ///invalidated.
402 402
    ///
403 403
    ///\warning This functionality cannot be used together with the Snapshot
404 404
    ///feature.
405 405
    void changeTarget(Arc a, Node n) {
406 406
      Parent::changeTarget(a,n);
407 407
    }
408 408
    /// Change the source of \c a to \c n
409 409

	
410 410
    /// Change the source of \c a to \c n
411 411
    ///
412 412
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
413 413
    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
414 414
    ///invalidated.
415 415
    ///
416 416
    ///\warning This functionality cannot be used together with the Snapshot
417 417
    ///feature.
418 418
    void changeSource(Arc a, Node n) {
419 419
      Parent::changeSource(a,n);
420 420
    }
421 421

	
422 422
    /// Invert the direction of an arc.
423 423

	
424 424
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
425 425
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
426 426
    ///invalidated.
427 427
    ///
428 428
    ///\warning This functionality cannot be used together with the Snapshot
429 429
    ///feature.
430 430
    void reverseArc(Arc e) {
431 431
      Node t=target(e);
432 432
      changeTarget(e,source(e));
433 433
      changeSource(e,t);
434 434
    }
435 435

	
436 436
    /// Reserve memory for nodes.
437 437

	
438 438
    /// Using this function it is possible to avoid the superfluous memory
439 439
    /// allocation: if you know that the digraph you want to build will
440 440
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
441 441
    /// then it is worth reserving space for this amount before starting
442 442
    /// to build the digraph.
443 443
    /// \sa reserveArc
444 444
    void reserveNode(int n) { nodes.reserve(n); };
445 445

	
446 446
    /// Reserve memory for arcs.
447 447

	
448 448
    /// Using this function it is possible to avoid the superfluous memory
449 449
    /// allocation: if you know that the digraph you want to build will
450 450
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
451 451
    /// then it is worth reserving space for this amount before starting
452 452
    /// to build the digraph.
453 453
    /// \sa reserveNode
454 454
    void reserveArc(int m) { arcs.reserve(m); };
455 455

	
456 456
    ///Contract two nodes.
457 457

	
458 458
    ///This function contracts two nodes.
459 459
    ///Node \p b will be removed but instead of deleting
460 460
    ///incident arcs, they will be joined to \p a.
461 461
    ///The last parameter \p r controls whether to remove loops. \c true
462 462
    ///means that loops will be removed.
463 463
    ///
464 464
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
465 465
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
466 466
    ///may be invalidated.
467 467
    ///
468 468
    ///\warning This functionality cannot be used together with the Snapshot
469 469
    ///feature.
470 470
    void contract(Node a, Node b, bool r = true)
471 471
    {
472 472
      for(OutArcIt e(*this,b);e!=INVALID;) {
473 473
        OutArcIt f=e;
474 474
        ++f;
475 475
        if(r && target(e)==a) erase(e);
476 476
        else changeSource(e,a);
477 477
        e=f;
478 478
      }
479 479
      for(InArcIt e(*this,b);e!=INVALID;) {
480 480
        InArcIt f=e;
481 481
        ++f;
482 482
        if(r && source(e)==a) erase(e);
483 483
        else changeTarget(e,a);
484 484
        e=f;
485 485
      }
486 486
      erase(b);
487 487
    }
488 488

	
489 489
    ///Split a node.
490 490

	
491 491
    ///This function splits a node. First a new node is added to the digraph,
492 492
    ///then the source of each outgoing arc of \c n is moved to this new node.
493 493
    ///If \c connect is \c true (this is the default value), then a new arc
494 494
    ///from \c n to the newly created node is also added.
495 495
    ///\return The newly created node.
496 496
    ///
497 497
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
498 498
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
499 499
    ///be invalidated.
500 500
    ///
501 501
    ///\warning This functionality cannot be used in conjunction with the
502 502
    ///Snapshot feature.
503 503
    Node split(Node n, bool connect = true) {
504 504
      Node b = addNode();
505 505
      for(OutArcIt e(*this,n);e!=INVALID;) {
506 506
        OutArcIt f=e;
507 507
        ++f;
508 508
        changeSource(e,b);
509 509
        e=f;
510 510
      }
511 511
      if (connect) addArc(n,b);
512 512
      return b;
513 513
    }
514 514

	
515 515
    ///Split an arc.
516 516

	
517 517
    ///This function splits an arc. First a new node \c b is added to
518 518
    ///the digraph, then the original arc is re-targeted to \c
519 519
    ///b. Finally an arc from \c b to the original target is added.
520 520
    ///
521 521
    ///\return The newly created node.
522 522
    ///
523 523
    ///\warning This functionality cannot be used together with the
524 524
    ///Snapshot feature.
525 525
    Node split(Arc e) {
526 526
      Node b = addNode();
527 527
      addArc(b,target(e));
528 528
      changeTarget(e,b);
529 529
      return b;
530 530
    }
531 531

	
532 532
    /// \brief Class to make a snapshot of the digraph and restore
533 533
    /// it later.
534 534
    ///
535 535
    /// Class to make a snapshot of the digraph and restore it later.
536 536
    ///
537 537
    /// The newly added nodes and arcs can be removed using the
538 538
    /// restore() function.
539 539
    ///
540 540
    /// \warning Arc and node deletions and other modifications (e.g.
541 541
    /// contracting, splitting, reversing arcs or nodes) cannot be
542 542
    /// restored. These events invalidate the snapshot.
543 543
    class Snapshot {
544 544
    protected:
545 545

	
546 546
      typedef Parent::NodeNotifier NodeNotifier;
547 547

	
548 548
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
549 549
      public:
550 550

	
551 551
        NodeObserverProxy(Snapshot& _snapshot)
552 552
          : snapshot(_snapshot) {}
553 553

	
554 554
        using NodeNotifier::ObserverBase::attach;
555 555
        using NodeNotifier::ObserverBase::detach;
556 556
        using NodeNotifier::ObserverBase::attached;
557 557

	
558 558
      protected:
559 559

	
560 560
        virtual void add(const Node& node) {
561 561
          snapshot.addNode(node);
562 562
        }
563 563
        virtual void add(const std::vector<Node>& nodes) {
564 564
          for (int i = nodes.size() - 1; i >= 0; ++i) {
565 565
            snapshot.addNode(nodes[i]);
566 566
          }
567 567
        }
568 568
        virtual void erase(const Node& node) {
569 569
          snapshot.eraseNode(node);
570 570
        }
571 571
        virtual void erase(const std::vector<Node>& nodes) {
572 572
          for (int i = 0; i < int(nodes.size()); ++i) {
573 573
            snapshot.eraseNode(nodes[i]);
574 574
          }
575 575
        }
576 576
        virtual void build() {
577 577
          Node node;
578 578
          std::vector<Node> nodes;
579 579
          for (notifier()->first(node); node != INVALID;
580 580
               notifier()->next(node)) {
581 581
            nodes.push_back(node);
582 582
          }
583 583
          for (int i = nodes.size() - 1; i >= 0; --i) {
584 584
            snapshot.addNode(nodes[i]);
585 585
          }
586 586
        }
587 587
        virtual void clear() {
588 588
          Node node;
589 589
          for (notifier()->first(node); node != INVALID;
590 590
               notifier()->next(node)) {
591 591
            snapshot.eraseNode(node);
592 592
          }
593 593
        }
594 594

	
595 595
        Snapshot& snapshot;
596 596
      };
597 597

	
598 598
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
599 599
      public:
600 600

	
601 601
        ArcObserverProxy(Snapshot& _snapshot)
602 602
          : snapshot(_snapshot) {}
603 603

	
604 604
        using ArcNotifier::ObserverBase::attach;
605 605
        using ArcNotifier::ObserverBase::detach;
606 606
        using ArcNotifier::ObserverBase::attached;
607 607

	
608 608
      protected:
609 609

	
610 610
        virtual void add(const Arc& arc) {
611 611
          snapshot.addArc(arc);
612 612
        }
613 613
        virtual void add(const std::vector<Arc>& arcs) {
614 614
          for (int i = arcs.size() - 1; i >= 0; ++i) {
615 615
            snapshot.addArc(arcs[i]);
616 616
          }
617 617
        }
618 618
        virtual void erase(const Arc& arc) {
619 619
          snapshot.eraseArc(arc);
620 620
        }
621 621
        virtual void erase(const std::vector<Arc>& arcs) {
622 622
          for (int i = 0; i < int(arcs.size()); ++i) {
623 623
            snapshot.eraseArc(arcs[i]);
624 624
          }
625 625
        }
626 626
        virtual void build() {
627 627
          Arc arc;
628 628
          std::vector<Arc> arcs;
629 629
          for (notifier()->first(arc); arc != INVALID;
630 630
               notifier()->next(arc)) {
631 631
            arcs.push_back(arc);
632 632
          }
633 633
          for (int i = arcs.size() - 1; i >= 0; --i) {
634 634
            snapshot.addArc(arcs[i]);
635 635
          }
636 636
        }
637 637
        virtual void clear() {
638 638
          Arc arc;
639 639
          for (notifier()->first(arc); arc != INVALID;
640 640
               notifier()->next(arc)) {
641 641
            snapshot.eraseArc(arc);
642 642
          }
643 643
        }
644 644

	
645 645
        Snapshot& snapshot;
646 646
      };
647 647

	
648 648
      ListDigraph *digraph;
649 649

	
650 650
      NodeObserverProxy node_observer_proxy;
651 651
      ArcObserverProxy arc_observer_proxy;
652 652

	
653 653
      std::list<Node> added_nodes;
654 654
      std::list<Arc> added_arcs;
655 655

	
656 656

	
657 657
      void addNode(const Node& node) {
658 658
        added_nodes.push_front(node);
659 659
      }
660 660
      void eraseNode(const Node& node) {
661 661
        std::list<Node>::iterator it =
662 662
          std::find(added_nodes.begin(), added_nodes.end(), node);
663 663
        if (it == added_nodes.end()) {
664 664
          clear();
665 665
          arc_observer_proxy.detach();
666 666
          throw NodeNotifier::ImmediateDetach();
667 667
        } else {
668 668
          added_nodes.erase(it);
669 669
        }
670 670
      }
671 671

	
672 672
      void addArc(const Arc& arc) {
673 673
        added_arcs.push_front(arc);
674 674
      }
675 675
      void eraseArc(const Arc& arc) {
676 676
        std::list<Arc>::iterator it =
677 677
          std::find(added_arcs.begin(), added_arcs.end(), arc);
678 678
        if (it == added_arcs.end()) {
679 679
          clear();
680 680
          node_observer_proxy.detach();
681 681
          throw ArcNotifier::ImmediateDetach();
682 682
        } else {
683 683
          added_arcs.erase(it);
684 684
        }
685 685
      }
686 686

	
687 687
      void attach(ListDigraph &_digraph) {
688 688
        digraph = &_digraph;
689 689
        node_observer_proxy.attach(digraph->notifier(Node()));
690 690
        arc_observer_proxy.attach(digraph->notifier(Arc()));
691 691
      }
692 692

	
693 693
      void detach() {
694 694
        node_observer_proxy.detach();
695 695
        arc_observer_proxy.detach();
696 696
      }
697 697

	
698 698
      bool attached() const {
699 699
        return node_observer_proxy.attached();
700 700
      }
701 701

	
702 702
      void clear() {
703 703
        added_nodes.clear();
704 704
        added_arcs.clear();
705 705
      }
706 706

	
707 707
    public:
708 708

	
709 709
      /// \brief Default constructor.
710 710
      ///
711 711
      /// Default constructor.
712 712
      /// To actually make a snapshot you must call save().
713 713
      Snapshot()
714 714
        : digraph(0), node_observer_proxy(*this),
715 715
          arc_observer_proxy(*this) {}
716 716

	
717 717
      /// \brief Constructor that immediately makes a snapshot.
718 718
      ///
719 719
      /// This constructor immediately makes a snapshot of the digraph.
720 720
      /// \param _digraph The digraph we make a snapshot of.
721 721
      Snapshot(ListDigraph &_digraph)
722 722
        : node_observer_proxy(*this),
723 723
          arc_observer_proxy(*this) {
724 724
        attach(_digraph);
725 725
      }
726 726

	
727 727
      /// \brief Make a snapshot.
728 728
      ///
729 729
      /// Make a snapshot of the digraph.
730 730
      ///
731 731
      /// This function can be called more than once. In case of a repeated
732 732
      /// call, the previous snapshot gets lost.
733 733
      /// \param _digraph The digraph we make the snapshot of.
734 734
      void save(ListDigraph &_digraph) {
735 735
        if (attached()) {
736 736
          detach();
737 737
          clear();
738 738
        }
739 739
        attach(_digraph);
740 740
      }
741 741

	
742 742
      /// \brief Undo the changes until the last snapshot.
743 743
      //
744 744
      /// Undo the changes until the last snapshot created by save().
745 745
      void restore() {
746 746
        detach();
747 747
        for(std::list<Arc>::iterator it = added_arcs.begin();
748 748
            it != added_arcs.end(); ++it) {
749 749
          digraph->erase(*it);
750 750
        }
751 751
        for(std::list<Node>::iterator it = added_nodes.begin();
752 752
            it != added_nodes.end(); ++it) {
753 753
          digraph->erase(*it);
754 754
        }
755 755
        clear();
756 756
      }
757 757

	
758 758
      /// \brief Gives back true when the snapshot is valid.
759 759
      ///
760 760
      /// Gives back true when the snapshot is valid.
761 761
      bool valid() const {
762 762
        return attached();
763 763
      }
764 764
    };
765 765

	
766 766
  };
767 767

	
768 768
  ///@}
769 769

	
770 770
  class ListGraphBase {
771 771

	
772 772
  protected:
773 773

	
774 774
    struct NodeT {
775 775
      int first_out;
776 776
      int prev, next;
777 777
    };
778 778

	
779 779
    struct ArcT {
780 780
      int target;
781 781
      int prev_out, next_out;
782 782
    };
783 783

	
784 784
    std::vector<NodeT> nodes;
785 785

	
786 786
    int first_node;
787 787

	
788 788
    int first_free_node;
789 789

	
790 790
    std::vector<ArcT> arcs;
791 791

	
792 792
    int first_free_arc;
793 793

	
794 794
  public:
795 795

	
796 796
    typedef ListGraphBase Graph;
797 797

	
798 798
    class Node;
799 799
    class Arc;
800 800
    class Edge;
801 801

	
802 802
    class Node {
803 803
      friend class ListGraphBase;
804 804
    protected:
805 805

	
806 806
      int id;
807 807
      explicit Node(int pid) { id = pid;}
808 808

	
809 809
    public:
810 810
      Node() {}
811 811
      Node (Invalid) { id = -1; }
812 812
      bool operator==(const Node& node) const {return id == node.id;}
813 813
      bool operator!=(const Node& node) const {return id != node.id;}
814 814
      bool operator<(const Node& node) const {return id < node.id;}
815 815
    };
816 816

	
817 817
    class Edge {
818 818
      friend class ListGraphBase;
819 819
    protected:
820 820

	
821 821
      int id;
822 822
      explicit Edge(int pid) { id = pid;}
823 823

	
824 824
    public:
825 825
      Edge() {}
826 826
      Edge (Invalid) { id = -1; }
827 827
      bool operator==(const Edge& edge) const {return id == edge.id;}
828 828
      bool operator!=(const Edge& edge) const {return id != edge.id;}
829 829
      bool operator<(const Edge& edge) const {return id < edge.id;}
830 830
    };
831 831

	
832 832
    class Arc {
833 833
      friend class ListGraphBase;
834 834
    protected:
835 835

	
836 836
      int id;
837 837
      explicit Arc(int pid) { id = pid;}
838 838

	
839 839
    public:
840 840
      operator Edge() const {
841 841
        return id != -1 ? edgeFromId(id / 2) : INVALID;
842 842
      }
843 843

	
844 844
      Arc() {}
845 845
      Arc (Invalid) { id = -1; }
846 846
      bool operator==(const Arc& arc) const {return id == arc.id;}
847 847
      bool operator!=(const Arc& arc) const {return id != arc.id;}
848 848
      bool operator<(const Arc& arc) const {return id < arc.id;}
849 849
    };
850 850

	
851 851

	
852 852

	
853 853
    ListGraphBase()
854 854
      : nodes(), first_node(-1),
855 855
        first_free_node(-1), arcs(), first_free_arc(-1) {}
856 856

	
857 857

	
858 858
    int maxNodeId() const { return nodes.size()-1; }
859 859
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
860 860
    int maxArcId() const { return arcs.size()-1; }
861 861

	
862 862
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
863 863
    Node target(Arc e) const { return Node(arcs[e.id].target); }
864 864

	
865 865
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
866 866
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
867 867

	
868 868
    static bool direction(Arc e) {
869 869
      return (e.id & 1) == 1;
870 870
    }
871 871

	
872 872
    static Arc direct(Edge e, bool d) {
873 873
      return Arc(e.id * 2 + (d ? 1 : 0));
874 874
    }
875 875

	
876 876
    void first(Node& node) const {
877 877
      node.id = first_node;
878 878
    }
879 879

	
880 880
    void next(Node& node) const {
881 881
      node.id = nodes[node.id].next;
882 882
    }
883 883

	
884 884
    void first(Arc& e) const {
885 885
      int n = first_node;
886 886
      while (n != -1 && nodes[n].first_out == -1) {
887 887
        n = nodes[n].next;
888 888
      }
889 889
      e.id = (n == -1) ? -1 : nodes[n].first_out;
890 890
    }
891 891

	
892 892
    void next(Arc& e) const {
893 893
      if (arcs[e.id].next_out != -1) {
894 894
        e.id = arcs[e.id].next_out;
895 895
      } else {
896 896
        int n = nodes[arcs[e.id ^ 1].target].next;
897 897
        while(n != -1 && nodes[n].first_out == -1) {
898 898
          n = nodes[n].next;
899 899
        }
900 900
        e.id = (n == -1) ? -1 : nodes[n].first_out;
0 comments (0 inline)