lemon/list_graph.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 732 bb70ad62c95f
parent 574 7a28e215f715
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@39
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@39
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
alpar@39
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@39
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@39
     8
 *
alpar@39
     9
 * Permission to use, modify and distribute this software is granted
alpar@39
    10
 * provided that this copyright notice appears in all copies. For
alpar@39
    11
 * precise terms see the accompanying LICENSE file.
alpar@39
    12
 *
alpar@39
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@39
    14
 * express or implied, and with no claim as to its suitability for any
alpar@39
    15
 * purpose.
alpar@39
    16
 *
alpar@39
    17
 */
alpar@39
    18
deba@57
    19
#ifndef LEMON_LIST_GRAPH_H
deba@57
    20
#define LEMON_LIST_GRAPH_H
deba@57
    21
deba@57
    22
///\ingroup graphs
deba@57
    23
///\file
deba@57
    24
///\brief ListDigraph, ListGraph classes.
deba@57
    25
deba@220
    26
#include <lemon/core.h>
deba@220
    27
#include <lemon/error.h>
deba@57
    28
#include <lemon/bits/graph_extender.h>
deba@57
    29
deba@57
    30
#include <vector>
deba@57
    31
#include <list>
deba@57
    32
deba@57
    33
namespace lemon {
deba@57
    34
deba@57
    35
  class ListDigraphBase {
deba@57
    36
deba@57
    37
  protected:
deba@57
    38
    struct NodeT {
deba@57
    39
      int first_in, first_out;
deba@57
    40
      int prev, next;
deba@57
    41
    };
alpar@209
    42
deba@57
    43
    struct ArcT {
deba@57
    44
      int target, source;
deba@57
    45
      int prev_in, prev_out;
deba@57
    46
      int next_in, next_out;
deba@57
    47
    };
deba@57
    48
deba@57
    49
    std::vector<NodeT> nodes;
deba@57
    50
deba@57
    51
    int first_node;
deba@57
    52
deba@57
    53
    int first_free_node;
deba@57
    54
deba@57
    55
    std::vector<ArcT> arcs;
deba@57
    56
deba@57
    57
    int first_free_arc;
alpar@209
    58
deba@57
    59
  public:
alpar@209
    60
deba@57
    61
    typedef ListDigraphBase Digraph;
alpar@209
    62
deba@57
    63
    class Node {
deba@57
    64
      friend class ListDigraphBase;
deba@57
    65
    protected:
deba@57
    66
deba@57
    67
      int id;
deba@57
    68
      explicit Node(int pid) { id = pid;}
deba@57
    69
deba@57
    70
    public:
deba@57
    71
      Node() {}
deba@57
    72
      Node (Invalid) { id = -1; }
deba@57
    73
      bool operator==(const Node& node) const {return id == node.id;}
deba@57
    74
      bool operator!=(const Node& node) const {return id != node.id;}
deba@57
    75
      bool operator<(const Node& node) const {return id < node.id;}
deba@57
    76
    };
deba@57
    77
deba@57
    78
    class Arc {
deba@57
    79
      friend class ListDigraphBase;
deba@57
    80
    protected:
deba@57
    81
deba@57
    82
      int id;
deba@57
    83
      explicit Arc(int pid) { id = pid;}
deba@57
    84
deba@57
    85
    public:
deba@57
    86
      Arc() {}
deba@57
    87
      Arc (Invalid) { id = -1; }
deba@57
    88
      bool operator==(const Arc& arc) const {return id == arc.id;}
deba@57
    89
      bool operator!=(const Arc& arc) const {return id != arc.id;}
deba@57
    90
      bool operator<(const Arc& arc) const {return id < arc.id;}
deba@57
    91
    };
deba@57
    92
deba@57
    93
deba@57
    94
deba@57
    95
    ListDigraphBase()
deba@57
    96
      : nodes(), first_node(-1),
alpar@209
    97
        first_free_node(-1), arcs(), first_free_arc(-1) {}
deba@57
    98
alpar@209
    99
alpar@209
   100
    int maxNodeId() const { return nodes.size()-1; }
deba@57
   101
    int maxArcId() const { return arcs.size()-1; }
deba@57
   102
deba@57
   103
    Node source(Arc e) const { return Node(arcs[e.id].source); }
deba@57
   104
    Node target(Arc e) const { return Node(arcs[e.id].target); }
deba@57
   105
deba@57
   106
alpar@209
   107
    void first(Node& node) const {
deba@57
   108
      node.id = first_node;
deba@57
   109
    }
deba@57
   110
deba@57
   111
    void next(Node& node) const {
deba@57
   112
      node.id = nodes[node.id].next;
deba@57
   113
    }
deba@57
   114
deba@57
   115
alpar@209
   116
    void first(Arc& arc) const {
deba@57
   117
      int n;
alpar@209
   118
      for(n = first_node;
alpar@209
   119
          n!=-1 && nodes[n].first_in == -1;
alpar@209
   120
          n = nodes[n].next) {}
kpeter@73
   121
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
deba@57
   122
    }
deba@57
   123
deba@57
   124
    void next(Arc& arc) const {
deba@57
   125
      if (arcs[arc.id].next_in != -1) {
alpar@209
   126
        arc.id = arcs[arc.id].next_in;
deba@57
   127
      } else {
alpar@209
   128
        int n;
alpar@209
   129
        for(n = nodes[arcs[arc.id].target].next;
alpar@209
   130
            n!=-1 && nodes[n].first_in == -1;
alpar@209
   131
            n = nodes[n].next) {}
alpar@209
   132
        arc.id = (n == -1) ? -1 : nodes[n].first_in;
alpar@209
   133
      }
deba@57
   134
    }
deba@57
   135
deba@57
   136
    void firstOut(Arc &e, const Node& v) const {
deba@57
   137
      e.id = nodes[v.id].first_out;
deba@57
   138
    }
deba@57
   139
    void nextOut(Arc &e) const {
deba@57
   140
      e.id=arcs[e.id].next_out;
deba@57
   141
    }
deba@57
   142
deba@57
   143
    void firstIn(Arc &e, const Node& v) const {
deba@57
   144
      e.id = nodes[v.id].first_in;
deba@57
   145
    }
deba@57
   146
    void nextIn(Arc &e) const {
deba@57
   147
      e.id=arcs[e.id].next_in;
deba@57
   148
    }
deba@57
   149
alpar@209
   150
deba@57
   151
    static int id(Node v) { return v.id; }
deba@57
   152
    static int id(Arc e) { return e.id; }
deba@57
   153
deba@57
   154
    static Node nodeFromId(int id) { return Node(id);}
deba@57
   155
    static Arc arcFromId(int id) { return Arc(id);}
deba@57
   156
alpar@209
   157
    bool valid(Node n) const {
alpar@209
   158
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
alpar@209
   159
        nodes[n.id].prev != -2;
deba@149
   160
    }
deba@149
   161
alpar@209
   162
    bool valid(Arc a) const {
alpar@209
   163
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
alpar@209
   164
        arcs[a.id].prev_in != -2;
deba@149
   165
    }
deba@149
   166
alpar@209
   167
    Node addNode() {
deba@57
   168
      int n;
alpar@209
   169
deba@57
   170
      if(first_free_node==-1) {
alpar@209
   171
        n = nodes.size();
alpar@209
   172
        nodes.push_back(NodeT());
deba@57
   173
      } else {
alpar@209
   174
        n = first_free_node;
alpar@209
   175
        first_free_node = nodes[n].next;
deba@57
   176
      }
alpar@209
   177
deba@57
   178
      nodes[n].next = first_node;
deba@57
   179
      if(first_node != -1) nodes[first_node].prev = n;
deba@57
   180
      first_node = n;
deba@57
   181
      nodes[n].prev = -1;
alpar@209
   182
deba@57
   183
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@209
   184
deba@57
   185
      return Node(n);
deba@57
   186
    }
alpar@209
   187
deba@57
   188
    Arc addArc(Node u, Node v) {
alpar@209
   189
      int n;
deba@57
   190
deba@57
   191
      if (first_free_arc == -1) {
alpar@209
   192
        n = arcs.size();
alpar@209
   193
        arcs.push_back(ArcT());
deba@57
   194
      } else {
alpar@209
   195
        n = first_free_arc;
alpar@209
   196
        first_free_arc = arcs[n].next_in;
deba@57
   197
      }
alpar@209
   198
alpar@209
   199
      arcs[n].source = u.id;
deba@57
   200
      arcs[n].target = v.id;
deba@57
   201
deba@57
   202
      arcs[n].next_out = nodes[u.id].first_out;
deba@57
   203
      if(nodes[u.id].first_out != -1) {
alpar@209
   204
        arcs[nodes[u.id].first_out].prev_out = n;
deba@57
   205
      }
alpar@209
   206
deba@57
   207
      arcs[n].next_in = nodes[v.id].first_in;
deba@57
   208
      if(nodes[v.id].first_in != -1) {
alpar@209
   209
        arcs[nodes[v.id].first_in].prev_in = n;
deba@57
   210
      }
alpar@209
   211
deba@57
   212
      arcs[n].prev_in = arcs[n].prev_out = -1;
alpar@209
   213
deba@57
   214
      nodes[u.id].first_out = nodes[v.id].first_in = n;
deba@57
   215
deba@57
   216
      return Arc(n);
deba@57
   217
    }
alpar@209
   218
deba@57
   219
    void erase(const Node& node) {
deba@57
   220
      int n = node.id;
alpar@209
   221
deba@57
   222
      if(nodes[n].next != -1) {
alpar@209
   223
        nodes[nodes[n].next].prev = nodes[n].prev;
deba@57
   224
      }
alpar@209
   225
deba@57
   226
      if(nodes[n].prev != -1) {
alpar@209
   227
        nodes[nodes[n].prev].next = nodes[n].next;
deba@57
   228
      } else {
alpar@209
   229
        first_node = nodes[n].next;
deba@57
   230
      }
alpar@209
   231
deba@57
   232
      nodes[n].next = first_free_node;
deba@57
   233
      first_free_node = n;
deba@149
   234
      nodes[n].prev = -2;
deba@57
   235
deba@57
   236
    }
alpar@209
   237
deba@57
   238
    void erase(const Arc& arc) {
deba@57
   239
      int n = arc.id;
alpar@209
   240
deba@57
   241
      if(arcs[n].next_in!=-1) {
alpar@209
   242
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
deba@57
   243
      }
deba@57
   244
deba@57
   245
      if(arcs[n].prev_in!=-1) {
alpar@209
   246
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
deba@57
   247
      } else {
alpar@209
   248
        nodes[arcs[n].target].first_in = arcs[n].next_in;
deba@57
   249
      }
deba@57
   250
alpar@209
   251
deba@57
   252
      if(arcs[n].next_out!=-1) {
alpar@209
   253
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
alpar@209
   254
      }
deba@57
   255
deba@57
   256
      if(arcs[n].prev_out!=-1) {
alpar@209
   257
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@57
   258
      } else {
alpar@209
   259
        nodes[arcs[n].source].first_out = arcs[n].next_out;
deba@57
   260
      }
alpar@209
   261
deba@57
   262
      arcs[n].next_in = first_free_arc;
deba@149
   263
      first_free_arc = n;
deba@149
   264
      arcs[n].prev_in = -2;
deba@57
   265
    }
deba@57
   266
deba@57
   267
    void clear() {
deba@57
   268
      arcs.clear();
deba@57
   269
      nodes.clear();
deba@57
   270
      first_node = first_free_node = first_free_arc = -1;
deba@57
   271
    }
deba@57
   272
deba@57
   273
  protected:
alpar@209
   274
    void changeTarget(Arc e, Node n)
deba@57
   275
    {
deba@57
   276
      if(arcs[e.id].next_in != -1)
alpar@209
   277
        arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
deba@57
   278
      if(arcs[e.id].prev_in != -1)
alpar@209
   279
        arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
deba@57
   280
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
deba@57
   281
      if (nodes[n.id].first_in != -1) {
alpar@209
   282
        arcs[nodes[n.id].first_in].prev_in = e.id;
deba@57
   283
      }
deba@57
   284
      arcs[e.id].target = n.id;
deba@57
   285
      arcs[e.id].prev_in = -1;
deba@57
   286
      arcs[e.id].next_in = nodes[n.id].first_in;
deba@57
   287
      nodes[n.id].first_in = e.id;
deba@57
   288
    }
alpar@209
   289
    void changeSource(Arc e, Node n)
deba@57
   290
    {
deba@57
   291
      if(arcs[e.id].next_out != -1)
alpar@209
   292
        arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
deba@57
   293
      if(arcs[e.id].prev_out != -1)
alpar@209
   294
        arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
deba@57
   295
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
deba@57
   296
      if (nodes[n.id].first_out != -1) {
alpar@209
   297
        arcs[nodes[n.id].first_out].prev_out = e.id;
deba@57
   298
      }
deba@57
   299
      arcs[e.id].source = n.id;
deba@57
   300
      arcs[e.id].prev_out = -1;
deba@57
   301
      arcs[e.id].next_out = nodes[n.id].first_out;
deba@57
   302
      nodes[n.id].first_out = e.id;
deba@57
   303
    }
deba@57
   304
deba@57
   305
  };
deba@57
   306
deba@57
   307
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
deba@57
   308
kpeter@73
   309
  /// \addtogroup graphs
deba@57
   310
  /// @{
deba@57
   311
alpar@209
   312
  ///A general directed graph structure.
deba@57
   313
alpar@209
   314
  ///\ref ListDigraph is a simple and fast <em>directed graph</em>
alpar@209
   315
  ///implementation based on static linked lists that are stored in
alpar@209
   316
  ///\c std::vector structures.
deba@57
   317
  ///
deba@57
   318
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
kpeter@73
   319
  ///also provides several useful additional functionalities.
kpeter@73
   320
  ///Most of the member functions and nested classes are documented
kpeter@73
   321
  ///only in the concept class.
deba@57
   322
  ///
kpeter@73
   323
  ///\sa concepts::Digraph
deba@57
   324
deba@57
   325
  class ListDigraph : public ExtendedListDigraphBase {
kpeter@609
   326
    typedef ExtendedListDigraphBase Parent;
kpeter@609
   327
deba@57
   328
  private:
kpeter@73
   329
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
alpar@209
   330
kpeter@73
   331
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
deba@57
   332
    ///
deba@57
   333
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
deba@57
   334
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
kpeter@73
   335
    ///Use copyDigraph() instead.
deba@57
   336
deba@57
   337
    ///Assignment of ListDigraph to another one is \e not allowed.
kpeter@73
   338
    ///Use copyDigraph() instead.
deba@57
   339
    void operator=(const ListDigraph &) {}
deba@57
   340
  public:
deba@57
   341
deba@57
   342
    /// Constructor
alpar@209
   343
deba@57
   344
    /// Constructor.
deba@57
   345
    ///
deba@57
   346
    ListDigraph() {}
deba@57
   347
deba@57
   348
    ///Add a new node to the digraph.
alpar@209
   349
kpeter@73
   350
    ///Add a new node to the digraph.
kpeter@550
   351
    ///\return The new node.
deba@57
   352
    Node addNode() { return Parent::addNode(); }
deba@57
   353
deba@57
   354
    ///Add a new arc to the digraph.
alpar@209
   355
deba@57
   356
    ///Add a new arc to the digraph with source node \c s
deba@57
   357
    ///and target node \c t.
kpeter@550
   358
    ///\return The new arc.
alpar@209
   359
    Arc addArc(const Node& s, const Node& t) {
alpar@209
   360
      return Parent::addArc(s, t);
deba@57
   361
    }
deba@57
   362
deba@234
   363
    ///\brief Erase a node from the digraph.
deba@234
   364
    ///
deba@234
   365
    ///Erase a node from the digraph.
deba@234
   366
    ///
deba@234
   367
    void erase(const Node& n) { Parent::erase(n); }
deba@234
   368
deba@234
   369
    ///\brief Erase an arc from the digraph.
deba@234
   370
    ///
deba@234
   371
    ///Erase an arc from the digraph.
deba@234
   372
    ///
deba@234
   373
    void erase(const Arc& a) { Parent::erase(a); }
deba@234
   374
deba@149
   375
    /// Node validity check
deba@149
   376
deba@149
   377
    /// This function gives back true if the given node is valid,
alpar@209
   378
    /// ie. it is a real node of the graph.
deba@149
   379
    ///
deba@149
   380
    /// \warning A Node pointing to a removed item
deba@149
   381
    /// could become valid again later if new nodes are
deba@149
   382
    /// added to the graph.
deba@149
   383
    bool valid(Node n) const { return Parent::valid(n); }
deba@149
   384
deba@149
   385
    /// Arc validity check
deba@149
   386
deba@149
   387
    /// This function gives back true if the given arc is valid,
alpar@209
   388
    /// ie. it is a real arc of the graph.
deba@149
   389
    ///
deba@149
   390
    /// \warning An Arc pointing to a removed item
deba@149
   391
    /// could become valid again later if new nodes are
deba@149
   392
    /// added to the graph.
deba@149
   393
    bool valid(Arc a) const { return Parent::valid(a); }
deba@149
   394
deba@235
   395
    /// Change the target of \c a to \c n
deba@57
   396
deba@235
   397
    /// Change the target of \c a to \c n
deba@57
   398
    ///
deba@57
   399
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
deba@57
   400
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
deba@57
   401
    ///invalidated.
kpeter@73
   402
    ///
deba@57
   403
    ///\warning This functionality cannot be used together with the Snapshot
deba@57
   404
    ///feature.
deba@235
   405
    void changeTarget(Arc a, Node n) {
deba@235
   406
      Parent::changeTarget(a,n);
deba@57
   407
    }
deba@235
   408
    /// Change the source of \c a to \c n
deba@57
   409
deba@235
   410
    /// Change the source of \c a to \c n
deba@57
   411
    ///
deba@235
   412
    ///\note The <tt>InArcIt</tt>s referencing the changed arc remain
kpeter@313
   413
    ///valid. However the <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s are
deba@57
   414
    ///invalidated.
kpeter@73
   415
    ///
deba@57
   416
    ///\warning This functionality cannot be used together with the Snapshot
deba@57
   417
    ///feature.
deba@235
   418
    void changeSource(Arc a, Node n) {
deba@235
   419
      Parent::changeSource(a,n);
deba@57
   420
    }
deba@57
   421
deba@57
   422
    /// Invert the direction of an arc.
deba@57
   423
deba@57
   424
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
deba@57
   425
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
deba@57
   426
    ///invalidated.
kpeter@73
   427
    ///
deba@57
   428
    ///\warning This functionality cannot be used together with the Snapshot
deba@57
   429
    ///feature.
deba@57
   430
    void reverseArc(Arc e) {
deba@57
   431
      Node t=target(e);
deba@57
   432
      changeTarget(e,source(e));
deba@57
   433
      changeSource(e,t);
deba@57
   434
    }
deba@57
   435
kpeter@73
   436
    /// Reserve memory for nodes.
kpeter@73
   437
kpeter@73
   438
    /// Using this function it is possible to avoid the superfluous memory
deba@57
   439
    /// allocation: if you know that the digraph you want to build will
deba@57
   440
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
deba@57
   441
    /// then it is worth reserving space for this amount before starting
deba@57
   442
    /// to build the digraph.
deba@57
   443
    /// \sa reserveArc
deba@57
   444
    void reserveNode(int n) { nodes.reserve(n); };
deba@57
   445
kpeter@73
   446
    /// Reserve memory for arcs.
deba@57
   447
kpeter@73
   448
    /// Using this function it is possible to avoid the superfluous memory
deba@57
   449
    /// allocation: if you know that the digraph you want to build will
deba@57
   450
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
deba@57
   451
    /// then it is worth reserving space for this amount before starting
deba@57
   452
    /// to build the digraph.
deba@57
   453
    /// \sa reserveNode
deba@57
   454
    void reserveArc(int m) { arcs.reserve(m); };
deba@57
   455
deba@57
   456
    ///Contract two nodes.
deba@57
   457
deba@57
   458
    ///This function contracts two nodes.
deba@57
   459
    ///Node \p b will be removed but instead of deleting
deba@57
   460
    ///incident arcs, they will be joined to \p a.
deba@57
   461
    ///The last parameter \p r controls whether to remove loops. \c true
deba@57
   462
    ///means that loops will be removed.
deba@57
   463
    ///
kpeter@73
   464
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
deba@57
   465
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
deba@57
   466
    ///may be invalidated.
kpeter@73
   467
    ///
deba@57
   468
    ///\warning This functionality cannot be used together with the Snapshot
deba@57
   469
    ///feature.
alpar@209
   470
    void contract(Node a, Node b, bool r = true)
deba@57
   471
    {
deba@57
   472
      for(OutArcIt e(*this,b);e!=INVALID;) {
alpar@209
   473
        OutArcIt f=e;
alpar@209
   474
        ++f;
alpar@209
   475
        if(r && target(e)==a) erase(e);
alpar@209
   476
        else changeSource(e,a);
alpar@209
   477
        e=f;
deba@57
   478
      }
deba@57
   479
      for(InArcIt e(*this,b);e!=INVALID;) {
alpar@209
   480
        InArcIt f=e;
alpar@209
   481
        ++f;
alpar@209
   482
        if(r && source(e)==a) erase(e);
alpar@209
   483
        else changeTarget(e,a);
alpar@209
   484
        e=f;
deba@57
   485
      }
deba@57
   486
      erase(b);
deba@57
   487
    }
deba@57
   488
deba@57
   489
    ///Split a node.
deba@57
   490
deba@57
   491
    ///This function splits a node. First a new node is added to the digraph,
deba@57
   492
    ///then the source of each outgoing arc of \c n is moved to this new node.
deba@57
   493
    ///If \c connect is \c true (this is the default value), then a new arc
deba@57
   494
    ///from \c n to the newly created node is also added.
deba@57
   495
    ///\return The newly created node.
deba@57
   496
    ///
deba@57
   497
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
deba@57
   498
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
alpar@209
   499
    ///be invalidated.
deba@57
   500
    ///
alpar@280
   501
    ///\warning This functionality cannot be used in conjunction with the
kpeter@73
   502
    ///Snapshot feature.
deba@57
   503
    Node split(Node n, bool connect = true) {
deba@57
   504
      Node b = addNode();
deba@57
   505
      for(OutArcIt e(*this,n);e!=INVALID;) {
kpeter@212
   506
        OutArcIt f=e;
alpar@209
   507
        ++f;
alpar@209
   508
        changeSource(e,b);
alpar@209
   509
        e=f;
deba@57
   510
      }
deba@57
   511
      if (connect) addArc(n,b);
deba@57
   512
      return b;
deba@57
   513
    }
alpar@209
   514
deba@57
   515
    ///Split an arc.
deba@57
   516
deba@57
   517
    ///This function splits an arc. First a new node \c b is added to
deba@57
   518
    ///the digraph, then the original arc is re-targeted to \c
deba@57
   519
    ///b. Finally an arc from \c b to the original target is added.
kpeter@73
   520
    ///
kpeter@73
   521
    ///\return The newly created node.
kpeter@73
   522
    ///
kpeter@73
   523
    ///\warning This functionality cannot be used together with the
kpeter@73
   524
    ///Snapshot feature.
deba@57
   525
    Node split(Arc e) {
deba@57
   526
      Node b = addNode();
deba@57
   527
      addArc(b,target(e));
deba@57
   528
      changeTarget(e,b);
deba@57
   529
      return b;
deba@57
   530
    }
alpar@209
   531
deba@57
   532
    /// \brief Class to make a snapshot of the digraph and restore
kpeter@73
   533
    /// it later.
deba@57
   534
    ///
kpeter@73
   535
    /// Class to make a snapshot of the digraph and restore it later.
deba@57
   536
    ///
deba@57
   537
    /// The newly added nodes and arcs can be removed using the
deba@57
   538
    /// restore() function.
deba@57
   539
    ///
kpeter@73
   540
    /// \warning Arc and node deletions and other modifications (e.g.
alpar@209
   541
    /// contracting, splitting, reversing arcs or nodes) cannot be
alpar@209
   542
    /// restored. These events invalidate the snapshot.
deba@57
   543
    class Snapshot {
deba@57
   544
    protected:
deba@57
   545
deba@57
   546
      typedef Parent::NodeNotifier NodeNotifier;
deba@57
   547
deba@57
   548
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
deba@57
   549
      public:
deba@57
   550
deba@57
   551
        NodeObserverProxy(Snapshot& _snapshot)
deba@57
   552
          : snapshot(_snapshot) {}
deba@57
   553
deba@57
   554
        using NodeNotifier::ObserverBase::attach;
deba@57
   555
        using NodeNotifier::ObserverBase::detach;
deba@57
   556
        using NodeNotifier::ObserverBase::attached;
alpar@209
   557
deba@57
   558
      protected:
alpar@209
   559
deba@57
   560
        virtual void add(const Node& node) {
deba@57
   561
          snapshot.addNode(node);
deba@57
   562
        }
deba@57
   563
        virtual void add(const std::vector<Node>& nodes) {
deba@57
   564
          for (int i = nodes.size() - 1; i >= 0; ++i) {
deba@57
   565
            snapshot.addNode(nodes[i]);
deba@57
   566
          }
deba@57
   567
        }
deba@57
   568
        virtual void erase(const Node& node) {
deba@57
   569
          snapshot.eraseNode(node);
deba@57
   570
        }
deba@57
   571
        virtual void erase(const std::vector<Node>& nodes) {
deba@57
   572
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@57
   573
            snapshot.eraseNode(nodes[i]);
deba@57
   574
          }
deba@57
   575
        }
deba@57
   576
        virtual void build() {
deba@57
   577
          Node node;
deba@57
   578
          std::vector<Node> nodes;
alpar@209
   579
          for (notifier()->first(node); node != INVALID;
deba@57
   580
               notifier()->next(node)) {
deba@57
   581
            nodes.push_back(node);
deba@57
   582
          }
deba@57
   583
          for (int i = nodes.size() - 1; i >= 0; --i) {
deba@57
   584
            snapshot.addNode(nodes[i]);
deba@57
   585
          }
deba@57
   586
        }
deba@57
   587
        virtual void clear() {
deba@57
   588
          Node node;
alpar@209
   589
          for (notifier()->first(node); node != INVALID;
deba@57
   590
               notifier()->next(node)) {
deba@57
   591
            snapshot.eraseNode(node);
deba@57
   592
          }
deba@57
   593
        }
deba@57
   594
deba@57
   595
        Snapshot& snapshot;
deba@57
   596
      };
deba@57
   597
deba@57
   598
      class ArcObserverProxy : public ArcNotifier::ObserverBase {
deba@57
   599
      public:
deba@57
   600
deba@57
   601
        ArcObserverProxy(Snapshot& _snapshot)
deba@57
   602
          : snapshot(_snapshot) {}
deba@57
   603
deba@57
   604
        using ArcNotifier::ObserverBase::attach;
deba@57
   605
        using ArcNotifier::ObserverBase::detach;
deba@57
   606
        using ArcNotifier::ObserverBase::attached;
alpar@209
   607
deba@57
   608
      protected:
deba@57
   609
deba@57
   610
        virtual void add(const Arc& arc) {
deba@57
   611
          snapshot.addArc(arc);
deba@57
   612
        }
deba@57
   613
        virtual void add(const std::vector<Arc>& arcs) {
deba@57
   614
          for (int i = arcs.size() - 1; i >= 0; ++i) {
deba@57
   615
            snapshot.addArc(arcs[i]);
deba@57
   616
          }
deba@57
   617
        }
deba@57
   618
        virtual void erase(const Arc& arc) {
deba@57
   619
          snapshot.eraseArc(arc);
deba@57
   620
        }
deba@57
   621
        virtual void erase(const std::vector<Arc>& arcs) {
deba@57
   622
          for (int i = 0; i < int(arcs.size()); ++i) {
deba@57
   623
            snapshot.eraseArc(arcs[i]);
deba@57
   624
          }
deba@57
   625
        }
deba@57
   626
        virtual void build() {
deba@57
   627
          Arc arc;
deba@57
   628
          std::vector<Arc> arcs;
alpar@209
   629
          for (notifier()->first(arc); arc != INVALID;
deba@57
   630
               notifier()->next(arc)) {
deba@57
   631
            arcs.push_back(arc);
deba@57
   632
          }
deba@57
   633
          for (int i = arcs.size() - 1; i >= 0; --i) {
deba@57
   634
            snapshot.addArc(arcs[i]);
deba@57
   635
          }
deba@57
   636
        }
deba@57
   637
        virtual void clear() {
deba@57
   638
          Arc arc;
alpar@209
   639
          for (notifier()->first(arc); arc != INVALID;
deba@57
   640
               notifier()->next(arc)) {
deba@57
   641
            snapshot.eraseArc(arc);
deba@57
   642
          }
deba@57
   643
        }
deba@57
   644
deba@57
   645
        Snapshot& snapshot;
deba@57
   646
      };
alpar@209
   647
deba@57
   648
      ListDigraph *digraph;
deba@57
   649
deba@57
   650
      NodeObserverProxy node_observer_proxy;
deba@57
   651
      ArcObserverProxy arc_observer_proxy;
deba@57
   652
deba@57
   653
      std::list<Node> added_nodes;
deba@57
   654
      std::list<Arc> added_arcs;
deba@57
   655
deba@57
   656
deba@57
   657
      void addNode(const Node& node) {
alpar@209
   658
        added_nodes.push_front(node);
deba@57
   659
      }
deba@57
   660
      void eraseNode(const Node& node) {
alpar@209
   661
        std::list<Node>::iterator it =
deba@57
   662
          std::find(added_nodes.begin(), added_nodes.end(), node);
deba@57
   663
        if (it == added_nodes.end()) {
deba@57
   664
          clear();
deba@57
   665
          arc_observer_proxy.detach();
deba@57
   666
          throw NodeNotifier::ImmediateDetach();
deba@57
   667
        } else {
deba@57
   668
          added_nodes.erase(it);
deba@57
   669
        }
deba@57
   670
      }
deba@57
   671
deba@57
   672
      void addArc(const Arc& arc) {
alpar@209
   673
        added_arcs.push_front(arc);
deba@57
   674
      }
deba@57
   675
      void eraseArc(const Arc& arc) {
alpar@209
   676
        std::list<Arc>::iterator it =
deba@57
   677
          std::find(added_arcs.begin(), added_arcs.end(), arc);
deba@57
   678
        if (it == added_arcs.end()) {
deba@57
   679
          clear();
alpar@209
   680
          node_observer_proxy.detach();
deba@57
   681
          throw ArcNotifier::ImmediateDetach();
deba@57
   682
        } else {
deba@57
   683
          added_arcs.erase(it);
alpar@209
   684
        }
deba@57
   685
      }
deba@57
   686
deba@57
   687
      void attach(ListDigraph &_digraph) {
alpar@209
   688
        digraph = &_digraph;
alpar@209
   689
        node_observer_proxy.attach(digraph->notifier(Node()));
deba@57
   690
        arc_observer_proxy.attach(digraph->notifier(Arc()));
deba@57
   691
      }
alpar@209
   692
deba@57
   693
      void detach() {
alpar@209
   694
        node_observer_proxy.detach();
alpar@209
   695
        arc_observer_proxy.detach();
deba@57
   696
      }
deba@57
   697
deba@57
   698
      bool attached() const {
deba@57
   699
        return node_observer_proxy.attached();
deba@57
   700
      }
deba@57
   701
deba@57
   702
      void clear() {
deba@57
   703
        added_nodes.clear();
alpar@209
   704
        added_arcs.clear();
deba@57
   705
      }
deba@57
   706
deba@57
   707
    public:
deba@57
   708
deba@57
   709
      /// \brief Default constructor.
deba@57
   710
      ///
deba@57
   711
      /// Default constructor.
deba@57
   712
      /// To actually make a snapshot you must call save().
alpar@209
   713
      Snapshot()
alpar@209
   714
        : digraph(0), node_observer_proxy(*this),
deba@57
   715
          arc_observer_proxy(*this) {}
alpar@209
   716
deba@57
   717
      /// \brief Constructor that immediately makes a snapshot.
alpar@209
   718
      ///
deba@57
   719
      /// This constructor immediately makes a snapshot of the digraph.
deba@57
   720
      /// \param _digraph The digraph we make a snapshot of.
alpar@209
   721
      Snapshot(ListDigraph &_digraph)
alpar@209
   722
        : node_observer_proxy(*this),
deba@57
   723
          arc_observer_proxy(*this) {
alpar@209
   724
        attach(_digraph);
deba@57
   725
      }
alpar@209
   726
deba@57
   727
      /// \brief Make a snapshot.
deba@57
   728
      ///
deba@57
   729
      /// Make a snapshot of the digraph.
deba@57
   730
      ///
deba@57
   731
      /// This function can be called more than once. In case of a repeated
deba@57
   732
      /// call, the previous snapshot gets lost.
deba@57
   733
      /// \param _digraph The digraph we make the snapshot of.
deba@57
   734
      void save(ListDigraph &_digraph) {
deba@57
   735
        if (attached()) {
deba@57
   736
          detach();
deba@57
   737
          clear();
deba@57
   738
        }
deba@57
   739
        attach(_digraph);
deba@57
   740
      }
alpar@209
   741
deba@57
   742
      /// \brief Undo the changes until the last snapshot.
alpar@209
   743
      //
deba@57
   744
      /// Undo the changes until the last snapshot created by save().
deba@57
   745
      void restore() {
alpar@209
   746
        detach();
alpar@209
   747
        for(std::list<Arc>::iterator it = added_arcs.begin();
deba@57
   748
            it != added_arcs.end(); ++it) {
alpar@209
   749
          digraph->erase(*it);
alpar@209
   750
        }
alpar@209
   751
        for(std::list<Node>::iterator it = added_nodes.begin();
deba@57
   752
            it != added_nodes.end(); ++it) {
alpar@209
   753
          digraph->erase(*it);
alpar@209
   754
        }
deba@57
   755
        clear();
deba@57
   756
      }
deba@57
   757
deba@57
   758
      /// \brief Gives back true when the snapshot is valid.
deba@57
   759
      ///
deba@57
   760
      /// Gives back true when the snapshot is valid.
deba@57
   761
      bool valid() const {
deba@57
   762
        return attached();
deba@57
   763
      }
deba@57
   764
    };
alpar@209
   765
deba@57
   766
  };
deba@57
   767
deba@57
   768
  ///@}
deba@57
   769
deba@57
   770
  class ListGraphBase {
deba@57
   771
deba@57
   772
  protected:
deba@57
   773
deba@57
   774
    struct NodeT {
deba@57
   775
      int first_out;
deba@57
   776
      int prev, next;
deba@57
   777
    };
alpar@209
   778
deba@57
   779
    struct ArcT {
deba@57
   780
      int target;
deba@57
   781
      int prev_out, next_out;
deba@57
   782
    };
deba@57
   783
deba@57
   784
    std::vector<NodeT> nodes;
deba@57
   785
deba@57
   786
    int first_node;
deba@57
   787
deba@57
   788
    int first_free_node;
deba@57
   789
deba@57
   790
    std::vector<ArcT> arcs;
deba@57
   791
deba@57
   792
    int first_free_arc;
alpar@209
   793
deba@57
   794
  public:
alpar@209
   795
kpeter@609
   796
    typedef ListGraphBase Graph;
deba@57
   797
deba@57
   798
    class Node;
deba@57
   799
    class Arc;
deba@57
   800
    class Edge;
alpar@209
   801
deba@57
   802
    class Node {
deba@57
   803
      friend class ListGraphBase;
deba@57
   804
    protected:
deba@57
   805
deba@57
   806
      int id;
deba@57
   807
      explicit Node(int pid) { id = pid;}
deba@57
   808
deba@57
   809
    public:
deba@57
   810
      Node() {}
deba@57
   811
      Node (Invalid) { id = -1; }
deba@57
   812
      bool operator==(const Node& node) const {return id == node.id;}
deba@57
   813
      bool operator!=(const Node& node) const {return id != node.id;}
deba@57
   814
      bool operator<(const Node& node) const {return id < node.id;}
deba@57
   815
    };
deba@57
   816
deba@57
   817
    class Edge {
deba@57
   818
      friend class ListGraphBase;
deba@57
   819
    protected:
deba@57
   820
deba@57
   821
      int id;
deba@57
   822
      explicit Edge(int pid) { id = pid;}
deba@57
   823
deba@57
   824
    public:
deba@57
   825
      Edge() {}
deba@57
   826
      Edge (Invalid) { id = -1; }
kpeter@73
   827
      bool operator==(const Edge& edge) const {return id == edge.id;}
kpeter@73
   828
      bool operator!=(const Edge& edge) const {return id != edge.id;}
kpeter@73
   829
      bool operator<(const Edge& edge) const {return id < edge.id;}
deba@57
   830
    };
deba@57
   831
deba@57
   832
    class Arc {
deba@57
   833
      friend class ListGraphBase;
deba@57
   834
    protected:
deba@57
   835
deba@57
   836
      int id;
deba@57
   837
      explicit Arc(int pid) { id = pid;}
deba@57
   838
deba@57
   839
    public:
kpeter@329
   840
      operator Edge() const {
kpeter@329
   841
        return id != -1 ? edgeFromId(id / 2) : INVALID;
deba@238
   842
      }
deba@57
   843
deba@57
   844
      Arc() {}
deba@57
   845
      Arc (Invalid) { id = -1; }
deba@57
   846
      bool operator==(const Arc& arc) const {return id == arc.id;}
deba@57
   847
      bool operator!=(const Arc& arc) const {return id != arc.id;}
deba@57
   848
      bool operator<(const Arc& arc) const {return id < arc.id;}
deba@57
   849
    };
deba@57
   850
deba@57
   851
deba@57
   852
deba@57
   853
    ListGraphBase()
deba@57
   854
      : nodes(), first_node(-1),
alpar@209
   855
        first_free_node(-1), arcs(), first_free_arc(-1) {}
deba@57
   856
alpar@209
   857
alpar@209
   858
    int maxNodeId() const { return nodes.size()-1; }
deba@57
   859
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@57
   860
    int maxArcId() const { return arcs.size()-1; }
deba@57
   861
deba@57
   862
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
deba@57
   863
    Node target(Arc e) const { return Node(arcs[e.id].target); }
deba@57
   864
deba@57
   865
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
deba@57
   866
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
deba@57
   867
deba@57
   868
    static bool direction(Arc e) {
deba@57
   869
      return (e.id & 1) == 1;
deba@57
   870
    }
deba@57
   871
deba@57
   872
    static Arc direct(Edge e, bool d) {
deba@57
   873
      return Arc(e.id * 2 + (d ? 1 : 0));
deba@57
   874
    }
deba@57
   875
alpar@209
   876
    void first(Node& node) const {
deba@57
   877
      node.id = first_node;
deba@57
   878
    }
deba@57
   879
deba@57
   880
    void next(Node& node) const {
deba@57
   881
      node.id = nodes[node.id].next;
deba@57
   882
    }
deba@57
   883
alpar@209
   884
    void first(Arc& e) const {
deba@57
   885
      int n = first_node;
deba@57
   886
      while (n != -1 && nodes[n].first_out == -1) {
deba@57
   887
        n = nodes[n].next;
deba@57
   888
      }
deba@57
   889
      e.id = (n == -1) ? -1 : nodes[n].first_out;
deba@57
   890
    }
deba@57
   891
deba@57
   892
    void next(Arc& e) const {
deba@57
   893
      if (arcs[e.id].next_out != -1) {
alpar@209
   894
        e.id = arcs[e.id].next_out;
deba@57
   895
      } else {
alpar@209
   896
        int n = nodes[arcs[e.id ^ 1].target].next;
deba@57
   897
        while(n != -1 && nodes[n].first_out == -1) {
deba@57
   898
          n = nodes[n].next;
deba@57
   899
        }
alpar@209
   900
        e.id = (n == -1) ? -1 : nodes[n].first_out;
alpar@209
   901
      }
deba@57
   902
    }
deba@57
   903
alpar@209
   904
    void first(Edge& e) const {
deba@57
   905
      int n = first_node;
deba@57
   906
      while (n != -1) {
deba@57
   907
        e.id = nodes[n].first_out;
deba@57
   908
        while ((e.id & 1) != 1) {
deba@57
   909
          e.id = arcs[e.id].next_out;
deba@57
   910
        }
deba@57
   911
        if (e.id != -1) {
deba@57
   912
          e.id /= 2;
deba@57
   913
          return;
alpar@209
   914
        }
deba@57
   915
        n = nodes[n].next;
deba@57
   916
      }
deba@57
   917
      e.id = -1;
deba@57
   918
    }
deba@57
   919
deba@57
   920
    void next(Edge& e) const {
deba@57
   921
      int n = arcs[e.id * 2].target;
deba@57
   922
      e.id = arcs[(e.id * 2) | 1].next_out;
deba@57
   923
      while ((e.id & 1) != 1) {
deba@57
   924
        e.id = arcs[e.id].next_out;
deba@57
   925
      }
deba@57
   926
      if (e.id != -1) {
deba@57
   927
        e.id /= 2;
deba@57
   928
        return;
alpar@209
   929
      }
deba@57
   930
      n = nodes[n].next;
deba@57
   931
      while (n != -1) {
deba@57
   932
        e.id = nodes[n].first_out;
deba@57
   933
        while ((e.id & 1) != 1) {
deba@57
   934
          e.id = arcs[e.id].next_out;
deba@57
   935
        }
deba@57
   936
        if (e.id != -1) {
deba@57
   937
          e.id /= 2;
deba@57
   938
          return;
alpar@209
   939
        }
deba@57
   940
        n = nodes[n].next;
deba@57
   941
      }
deba@57
   942
      e.id = -1;
deba@57
   943
    }
deba@57
   944
deba@57
   945
    void firstOut(Arc &e, const Node& v) const {
deba@57
   946
      e.id = nodes[v.id].first_out;
deba@57
   947
    }
deba@57
   948
    void nextOut(Arc &e) const {
deba@57
   949
      e.id = arcs[e.id].next_out;
deba@57
   950
    }
deba@57
   951
deba@57
   952
    void firstIn(Arc &e, const Node& v) const {
deba@57
   953
      e.id = ((nodes[v.id].first_out) ^ 1);
deba@57
   954
      if (e.id == -2) e.id = -1;
deba@57
   955
    }
deba@57
   956
    void nextIn(Arc &e) const {
deba@57
   957
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
deba@57
   958
      if (e.id == -2) e.id = -1;
deba@57
   959
    }
deba@57
   960
deba@57
   961
    void firstInc(Edge &e, bool& d, const Node& v) const {
kpeter@73
   962
      int a = nodes[v.id].first_out;
kpeter@73
   963
      if (a != -1 ) {
kpeter@73
   964
        e.id = a / 2;
kpeter@73
   965
        d = ((a & 1) == 1);
deba@57
   966
      } else {
deba@57
   967
        e.id = -1;
deba@57
   968
        d = true;
deba@57
   969
      }
deba@57
   970
    }
deba@57
   971
    void nextInc(Edge &e, bool& d) const {
kpeter@73
   972
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
kpeter@73
   973
      if (a != -1 ) {
kpeter@73
   974
        e.id = a / 2;
kpeter@73
   975
        d = ((a & 1) == 1);
deba@57
   976
      } else {
deba@57
   977
        e.id = -1;
deba@57
   978
        d = true;
deba@57
   979
      }
deba@57
   980
    }
alpar@209
   981
deba@57
   982
    static int id(Node v) { return v.id; }
deba@57
   983
    static int id(Arc e) { return e.id; }
deba@57
   984
    static int id(Edge e) { return e.id; }
deba@57
   985
deba@57
   986
    static Node nodeFromId(int id) { return Node(id);}
deba@57
   987
    static Arc arcFromId(int id) { return Arc(id);}
deba@57
   988
    static Edge edgeFromId(int id) { return Edge(id);}
deba@57
   989
alpar@209
   990
    bool valid(Node n) const {
alpar@209
   991
      return n.id >= 0 && n.id < static_cast<int>(nodes.size()) &&
alpar@209
   992
        nodes[n.id].prev != -2;
deba@149
   993
    }
deba@149
   994
alpar@209
   995
    bool valid(Arc a) const {
alpar@209
   996
      return a.id >= 0 && a.id < static_cast<int>(arcs.size()) &&
alpar@209
   997
        arcs[a.id].prev_out != -2;
deba@149
   998
    }
deba@149
   999
alpar@209
  1000
    bool valid(Edge e) const {
alpar@209
  1001
      return e.id >= 0 && 2 * e.id < static_cast<int>(arcs.size()) &&
alpar@209
  1002
        arcs[2 * e.id].prev_out != -2;
deba@149
  1003
    }
deba@149
  1004
alpar@209
  1005
    Node addNode() {
deba@57
  1006
      int n;
alpar@209
  1007
deba@57
  1008
      if(first_free_node==-1) {
alpar@209
  1009
        n = nodes.size();
alpar@209
  1010
        nodes.push_back(NodeT());
deba@57
  1011
      } else {
alpar@209
  1012
        n = first_free_node;
alpar@209
  1013
        first_free_node = nodes[n].next;
deba@57
  1014
      }
alpar@209
  1015
deba@57
  1016
      nodes[n].next = first_node;
deba@57
  1017
      if (first_node != -1) nodes[first_node].prev = n;
deba@57
  1018
      first_node = n;
deba@57
  1019
      nodes[n].prev = -1;
alpar@209
  1020
deba@57
  1021
      nodes[n].first_out = -1;
alpar@209
  1022
deba@57
  1023
      return Node(n);
deba@57
  1024
    }
alpar@209
  1025
deba@57
  1026
    Edge addEdge(Node u, Node v) {
alpar@209
  1027
      int n;
deba@57
  1028
deba@57
  1029
      if (first_free_arc == -1) {
alpar@209
  1030
        n = arcs.size();
alpar@209
  1031
        arcs.push_back(ArcT());
alpar@209
  1032
        arcs.push_back(ArcT());
deba@57
  1033
      } else {
alpar@209
  1034
        n = first_free_arc;
alpar@209
  1035
        first_free_arc = arcs[n].next_out;
deba@57
  1036
      }
alpar@209
  1037
deba@57
  1038
      arcs[n].target = u.id;
deba@57
  1039
      arcs[n | 1].target = v.id;
deba@57
  1040
deba@57
  1041
      arcs[n].next_out = nodes[v.id].first_out;
deba@57
  1042
      if (nodes[v.id].first_out != -1) {
alpar@209
  1043
        arcs[nodes[v.id].first_out].prev_out = n;
alpar@209
  1044
      }
deba@57
  1045
      arcs[n].prev_out = -1;
deba@57
  1046
      nodes[v.id].first_out = n;
alpar@209
  1047
deba@57
  1048
      arcs[n | 1].next_out = nodes[u.id].first_out;
deba@57
  1049
      if (nodes[u.id].first_out != -1) {
alpar@209
  1050
        arcs[nodes[u.id].first_out].prev_out = (n | 1);
deba@57
  1051
      }
alpar@209
  1052
      arcs[n | 1].prev_out = -1;
deba@57
  1053
      nodes[u.id].first_out = (n | 1);
deba@57
  1054
deba@57
  1055
      return Edge(n / 2);
deba@57
  1056
    }
alpar@209
  1057
deba@57
  1058
    void erase(const Node& node) {
deba@57
  1059
      int n = node.id;
alpar@209
  1060
deba@57
  1061
      if(nodes[n].next != -1) {
alpar@209
  1062
        nodes[nodes[n].next].prev = nodes[n].prev;
deba@57
  1063
      }
alpar@209
  1064
deba@57
  1065
      if(nodes[n].prev != -1) {
alpar@209
  1066
        nodes[nodes[n].prev].next = nodes[n].next;
deba@57
  1067
      } else {
alpar@209
  1068
        first_node = nodes[n].next;
deba@57
  1069
      }
alpar@209
  1070
deba@57
  1071
      nodes[n].next = first_free_node;
deba@57
  1072
      first_free_node = n;
deba@149
  1073
      nodes[n].prev = -2;
deba@57
  1074
    }
alpar@209
  1075
kpeter@73
  1076
    void erase(const Edge& edge) {
kpeter@73
  1077
      int n = edge.id * 2;
alpar@209
  1078
deba@57
  1079
      if (arcs[n].next_out != -1) {
alpar@209
  1080
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
alpar@209
  1081
      }
deba@57
  1082
deba@57
  1083
      if (arcs[n].prev_out != -1) {
alpar@209
  1084
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@57
  1085
      } else {
alpar@209
  1086
        nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
deba@57
  1087
      }
deba@57
  1088
deba@57
  1089
      if (arcs[n | 1].next_out != -1) {
alpar@209
  1090
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
alpar@209
  1091
      }
deba@57
  1092
deba@57
  1093
      if (arcs[n | 1].prev_out != -1) {
alpar@209
  1094
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
deba@57
  1095
      } else {
alpar@209
  1096
        nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
deba@57
  1097
      }
alpar@209
  1098
deba@57
  1099
      arcs[n].next_out = first_free_arc;
alpar@209
  1100
      first_free_arc = n;
deba@149
  1101
      arcs[n].prev_out = -2;
deba@149
  1102
      arcs[n | 1].prev_out = -2;
deba@57
  1103
deba@57
  1104
    }
deba@57
  1105
deba@57
  1106
    void clear() {
deba@57
  1107
      arcs.clear();
deba@57
  1108
      nodes.clear();
deba@57
  1109
      first_node = first_free_node = first_free_arc = -1;
deba@57
  1110
    }
deba@57
  1111
deba@57
  1112
  protected:
deba@57
  1113
deba@235
  1114
    void changeV(Edge e, Node n) {
deba@57
  1115
      if(arcs[2 * e.id].next_out != -1) {
alpar@209
  1116
        arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
deba@57
  1117
      }
deba@57
  1118
      if(arcs[2 * e.id].prev_out != -1) {
alpar@209
  1119
        arcs[arcs[2 * e.id].prev_out].next_out =
deba@57
  1120
          arcs[2 * e.id].next_out;
deba@57
  1121
      } else {
alpar@209
  1122
        nodes[arcs[(2 * e.id) | 1].target].first_out =
deba@57
  1123
          arcs[2 * e.id].next_out;
deba@57
  1124
      }
deba@57
  1125
deba@57
  1126
      if (nodes[n.id].first_out != -1) {
alpar@209
  1127
        arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
deba@57
  1128
      }
deba@57
  1129
      arcs[(2 * e.id) | 1].target = n.id;
deba@57
  1130
      arcs[2 * e.id].prev_out = -1;
deba@57
  1131
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
deba@57
  1132
      nodes[n.id].first_out = 2 * e.id;
deba@57
  1133
    }
deba@57
  1134
deba@235
  1135
    void changeU(Edge e, Node n) {
deba@57
  1136
      if(arcs[(2 * e.id) | 1].next_out != -1) {
alpar@209
  1137
        arcs[arcs[(2 * e.id) | 1].next_out].prev_out =
deba@57
  1138
          arcs[(2 * e.id) | 1].prev_out;
deba@57
  1139
      }
deba@57
  1140
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
alpar@209
  1141
        arcs[arcs[(2 * e.id) | 1].prev_out].next_out =
deba@57
  1142
          arcs[(2 * e.id) | 1].next_out;
deba@57
  1143
      } else {
alpar@209
  1144
        nodes[arcs[2 * e.id].target].first_out =
deba@57
  1145
          arcs[(2 * e.id) | 1].next_out;
deba@57
  1146
      }
deba@57
  1147
deba@57
  1148
      if (nodes[n.id].first_out != -1) {
alpar@209
  1149
        arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
deba@57
  1150
      }
deba@57
  1151
      arcs[2 * e.id].target = n.id;
deba@57
  1152
      arcs[(2 * e.id) | 1].prev_out = -1;
deba@57
  1153
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
deba@57
  1154
      nodes[n.id].first_out = ((2 * e.id) | 1);
deba@57
  1155
    }
deba@57
  1156
deba@57
  1157
  };
deba@57
  1158
deba@57
  1159
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
deba@57
  1160
deba@57
  1161
kpeter@73
  1162
  /// \addtogroup graphs
deba@57
  1163
  /// @{
deba@57
  1164
kpeter@73
  1165
  ///A general undirected graph structure.
deba@57
  1166
alpar@209
  1167
  ///\ref ListGraph is a simple and fast <em>undirected graph</em>
alpar@209
  1168
  ///implementation based on static linked lists that are stored in
alpar@209
  1169
  ///\c std::vector structures.
deba@57
  1170
  ///
kpeter@73
  1171
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
kpeter@73
  1172
  ///also provides several useful additional functionalities.
kpeter@73
  1173
  ///Most of the member functions and nested classes are documented
kpeter@73
  1174
  ///only in the concept class.
kpeter@73
  1175
  ///
kpeter@73
  1176
  ///\sa concepts::Graph
kpeter@73
  1177
deba@57
  1178
  class ListGraph : public ExtendedListGraphBase {
kpeter@609
  1179
    typedef ExtendedListGraphBase Parent;
kpeter@609
  1180
deba@57
  1181
  private:
kpeter@73
  1182
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
deba@57
  1183
kpeter@73
  1184
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
deba@57
  1185
    ///
deba@57
  1186
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
deba@57
  1187
    ///\brief Assignment of ListGraph to another one is \e not allowed.
kpeter@73
  1188
    ///Use copyGraph() instead.
deba@57
  1189
deba@57
  1190
    ///Assignment of ListGraph to another one is \e not allowed.
kpeter@73
  1191
    ///Use copyGraph() instead.
deba@57
  1192
    void operator=(const ListGraph &) {}
deba@57
  1193
  public:
deba@57
  1194
    /// Constructor
alpar@209
  1195
deba@57
  1196
    /// Constructor.
deba@57
  1197
    ///
deba@57
  1198
    ListGraph() {}
deba@57
  1199
kpeter@73
  1200
    typedef Parent::OutArcIt IncEdgeIt;
deba@57
  1201
kpeter@73
  1202
    /// \brief Add a new node to the graph.
deba@57
  1203
    ///
kpeter@73
  1204
    /// Add a new node to the graph.
kpeter@550
  1205
    /// \return The new node.
deba@57
  1206
    Node addNode() { return Parent::addNode(); }
deba@57
  1207
kpeter@73
  1208
    /// \brief Add a new edge to the graph.
deba@57
  1209
    ///
kpeter@73
  1210
    /// Add a new edge to the graph with source node \c s
deba@57
  1211
    /// and target node \c t.
kpeter@550
  1212
    /// \return The new edge.
alpar@209
  1213
    Edge addEdge(const Node& s, const Node& t) {
alpar@209
  1214
      return Parent::addEdge(s, t);
deba@57
  1215
    }
deba@234
  1216
deba@234
  1217
    /// \brief Erase a node from the graph.
deba@234
  1218
    ///
deba@234
  1219
    /// Erase a node from the graph.
deba@234
  1220
    ///
deba@234
  1221
    void erase(const Node& n) { Parent::erase(n); }
deba@234
  1222
deba@234
  1223
    /// \brief Erase an edge from the graph.
deba@234
  1224
    ///
deba@234
  1225
    /// Erase an edge from the graph.
deba@234
  1226
    ///
deba@234
  1227
    void erase(const Edge& e) { Parent::erase(e); }
deba@149
  1228
    /// Node validity check
deba@149
  1229
deba@149
  1230
    /// This function gives back true if the given node is valid,
alpar@209
  1231
    /// ie. it is a real node of the graph.
deba@149
  1232
    ///
deba@149
  1233
    /// \warning A Node pointing to a removed item
deba@149
  1234
    /// could become valid again later if new nodes are
deba@149
  1235
    /// added to the graph.
deba@149
  1236
    bool valid(Node n) const { return Parent::valid(n); }
deba@149
  1237
    /// Arc validity check
deba@149
  1238
deba@149
  1239
    /// This function gives back true if the given arc is valid,
alpar@209
  1240
    /// ie. it is a real arc of the graph.
deba@149
  1241
    ///
deba@149
  1242
    /// \warning An Arc pointing to a removed item
deba@149
  1243
    /// could become valid again later if new edges are
deba@149
  1244
    /// added to the graph.
deba@149
  1245
    bool valid(Arc a) const { return Parent::valid(a); }
deba@149
  1246
    /// Edge validity check
deba@149
  1247
deba@149
  1248
    /// This function gives back true if the given edge is valid,
alpar@209
  1249
    /// ie. it is a real arc of the graph.
deba@149
  1250
    ///
deba@149
  1251
    /// \warning A Edge pointing to a removed item
deba@149
  1252
    /// could become valid again later if new edges are
deba@149
  1253
    /// added to the graph.
deba@149
  1254
    bool valid(Edge e) const { return Parent::valid(e); }
deba@235
  1255
    /// \brief Change the end \c u of \c e to \c n
deba@57
  1256
    ///
deba@235
  1257
    /// This function changes the end \c u of \c e to node \c n.
deba@57
  1258
    ///
deba@235
  1259
    ///\note The <tt>EdgeIt</tt>s and <tt>ArcIt</tt>s referencing the
deba@235
  1260
    ///changed edge are invalidated and if the changed node is the
deba@235
  1261
    ///base node of an iterator then this iterator is also
deba@235
  1262
    ///invalidated.
kpeter@73
  1263
    ///
kpeter@73
  1264
    ///\warning This functionality cannot be used together with the
kpeter@73
  1265
    ///Snapshot feature.
deba@235
  1266
    void changeU(Edge e, Node n) {
deba@235
  1267
      Parent::changeU(e,n);
alpar@209
  1268
    }
deba@235
  1269
    /// \brief Change the end \c v of \c e to \c n
deba@57
  1270
    ///
deba@235
  1271
    /// This function changes the end \c v of \c e to \c n.
deba@57
  1272
    ///
deba@235
  1273
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
deba@235
  1274
    ///valid, however <tt>ArcIt</tt>s and if the changed node is the
deba@235
  1275
    ///base node of an iterator then this iterator is invalidated.
kpeter@73
  1276
    ///
kpeter@73
  1277
    ///\warning This functionality cannot be used together with the
kpeter@73
  1278
    ///Snapshot feature.
deba@235
  1279
    void changeV(Edge e, Node n) {
deba@235
  1280
      Parent::changeV(e,n);
deba@57
  1281
    }
deba@57
  1282
    /// \brief Contract two nodes.
deba@57
  1283
    ///
deba@57
  1284
    /// This function contracts two nodes.
deba@57
  1285
    /// Node \p b will be removed but instead of deleting
deba@57
  1286
    /// its neighboring arcs, they will be joined to \p a.
deba@57
  1287
    /// The last parameter \p r controls whether to remove loops. \c true
deba@57
  1288
    /// means that loops will be removed.
deba@57
  1289
    ///
deba@57
  1290
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
deba@57
  1291
    /// valid.
kpeter@73
  1292
    ///
kpeter@73
  1293
    ///\warning This functionality cannot be used together with the
kpeter@73
  1294
    ///Snapshot feature.
deba@57
  1295
    void contract(Node a, Node b, bool r = true) {
kpeter@73
  1296
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
alpar@209
  1297
        IncEdgeIt f = e; ++f;
alpar@209
  1298
        if (r && runningNode(e) == a) {
alpar@209
  1299
          erase(e);
deba@235
  1300
        } else if (u(e) == b) {
deba@235
  1301
          changeU(e, a);
alpar@209
  1302
        } else {
deba@235
  1303
          changeV(e, a);
alpar@209
  1304
        }
alpar@209
  1305
        e = f;
deba@57
  1306
      }
deba@57
  1307
      erase(b);
deba@57
  1308
    }
deba@57
  1309
deba@57
  1310
kpeter@73
  1311
    /// \brief Class to make a snapshot of the graph and restore
kpeter@73
  1312
    /// it later.
deba@57
  1313
    ///
kpeter@73
  1314
    /// Class to make a snapshot of the graph and restore it later.
deba@57
  1315
    ///
deba@57
  1316
    /// The newly added nodes and edges can be removed
deba@57
  1317
    /// using the restore() function.
deba@57
  1318
    ///
kpeter@73
  1319
    /// \warning Edge and node deletions and other modifications
alpar@209
  1320
    /// (e.g. changing nodes of edges, contracting nodes) cannot be
kpeter@73
  1321
    /// restored. These events invalidate the snapshot.
deba@57
  1322
    class Snapshot {
deba@57
  1323
    protected:
deba@57
  1324
deba@57
  1325
      typedef Parent::NodeNotifier NodeNotifier;
deba@57
  1326
deba@57
  1327
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
deba@57
  1328
      public:
deba@57
  1329
deba@57
  1330
        NodeObserverProxy(Snapshot& _snapshot)
deba@57
  1331
          : snapshot(_snapshot) {}
deba@57
  1332
deba@57
  1333
        using NodeNotifier::ObserverBase::attach;
deba@57
  1334
        using NodeNotifier::ObserverBase::detach;
deba@57
  1335
        using NodeNotifier::ObserverBase::attached;
alpar@209
  1336
deba@57
  1337
      protected:
alpar@209
  1338
deba@57
  1339
        virtual void add(const Node& node) {
deba@57
  1340
          snapshot.addNode(node);
deba@57
  1341
        }
deba@57
  1342
        virtual void add(const std::vector<Node>& nodes) {
deba@57
  1343
          for (int i = nodes.size() - 1; i >= 0; ++i) {
deba@57
  1344
            snapshot.addNode(nodes[i]);
deba@57
  1345
          }
deba@57
  1346
        }
deba@57
  1347
        virtual void erase(const Node& node) {
deba@57
  1348
          snapshot.eraseNode(node);
deba@57
  1349
        }
deba@57
  1350
        virtual void erase(const std::vector<Node>& nodes) {
deba@57
  1351
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@57
  1352
            snapshot.eraseNode(nodes[i]);
deba@57
  1353
          }
deba@57
  1354
        }
deba@57
  1355
        virtual void build() {
deba@57
  1356
          Node node;
deba@57
  1357
          std::vector<Node> nodes;
alpar@209
  1358
          for (notifier()->first(node); node != INVALID;
deba@57
  1359
               notifier()->next(node)) {
deba@57
  1360
            nodes.push_back(node);
deba@57
  1361
          }
deba@57
  1362
          for (int i = nodes.size() - 1; i >= 0; --i) {
deba@57
  1363
            snapshot.addNode(nodes[i]);
deba@57
  1364
          }
deba@57
  1365
        }
deba@57
  1366
        virtual void clear() {
deba@57
  1367
          Node node;
alpar@209
  1368
          for (notifier()->first(node); node != INVALID;
deba@57
  1369
               notifier()->next(node)) {
deba@57
  1370
            snapshot.eraseNode(node);
deba@57
  1371
          }
deba@57
  1372
        }
deba@57
  1373
deba@57
  1374
        Snapshot& snapshot;
deba@57
  1375
      };
deba@57
  1376
deba@57
  1377
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
deba@57
  1378
      public:
deba@57
  1379
deba@57
  1380
        EdgeObserverProxy(Snapshot& _snapshot)
deba@57
  1381
          : snapshot(_snapshot) {}
deba@57
  1382
deba@57
  1383
        using EdgeNotifier::ObserverBase::attach;
deba@57
  1384
        using EdgeNotifier::ObserverBase::detach;
deba@57
  1385
        using EdgeNotifier::ObserverBase::attached;
alpar@209
  1386
deba@57
  1387
      protected:
deba@57
  1388
kpeter@73
  1389
        virtual void add(const Edge& edge) {
kpeter@73
  1390
          snapshot.addEdge(edge);
deba@57
  1391
        }
kpeter@73
  1392
        virtual void add(const std::vector<Edge>& edges) {
kpeter@73
  1393
          for (int i = edges.size() - 1; i >= 0; ++i) {
kpeter@73
  1394
            snapshot.addEdge(edges[i]);
deba@57
  1395
          }
deba@57
  1396
        }
kpeter@73
  1397
        virtual void erase(const Edge& edge) {
kpeter@73
  1398
          snapshot.eraseEdge(edge);
deba@57
  1399
        }
kpeter@73
  1400
        virtual void erase(const std::vector<Edge>& edges) {
kpeter@73
  1401
          for (int i = 0; i < int(edges.size()); ++i) {
kpeter@73
  1402
            snapshot.eraseEdge(edges[i]);
deba@57
  1403
          }
deba@57
  1404
        }
deba@57
  1405
        virtual void build() {
kpeter@73
  1406
          Edge edge;
kpeter@73
  1407
          std::vector<Edge> edges;
alpar@209
  1408
          for (notifier()->first(edge); edge != INVALID;
kpeter@73
  1409
               notifier()->next(edge)) {
kpeter@73
  1410
            edges.push_back(edge);
deba@57
  1411
          }
kpeter@73
  1412
          for (int i = edges.size() - 1; i >= 0; --i) {
kpeter@73
  1413
            snapshot.addEdge(edges[i]);
deba@57
  1414
          }
deba@57
  1415
        }
deba@57
  1416
        virtual void clear() {
kpeter@73
  1417
          Edge edge;
alpar@209
  1418
          for (notifier()->first(edge); edge != INVALID;
kpeter@73
  1419
               notifier()->next(edge)) {
kpeter@73
  1420
            snapshot.eraseEdge(edge);
deba@57
  1421
          }
deba@57
  1422
        }
deba@57
  1423
deba@57
  1424
        Snapshot& snapshot;
deba@57
  1425
      };
kpeter@73
  1426
kpeter@73
  1427
      ListGraph *graph;
deba@57
  1428
deba@57
  1429
      NodeObserverProxy node_observer_proxy;
kpeter@73
  1430
      EdgeObserverProxy edge_observer_proxy;
deba@57
  1431
deba@57
  1432
      std::list<Node> added_nodes;
kpeter@73
  1433
      std::list<Edge> added_edges;
deba@57
  1434
deba@57
  1435
deba@57
  1436
      void addNode(const Node& node) {
alpar@209
  1437
        added_nodes.push_front(node);
deba@57
  1438
      }
deba@57
  1439
      void eraseNode(const Node& node) {
alpar@209
  1440
        std::list<Node>::iterator it =
deba@57
  1441
          std::find(added_nodes.begin(), added_nodes.end(), node);
deba@57
  1442
        if (it == added_nodes.end()) {
deba@57
  1443
          clear();
kpeter@73
  1444
          edge_observer_proxy.detach();
deba@57
  1445
          throw NodeNotifier::ImmediateDetach();
deba@57
  1446
        } else {
deba@57
  1447
          added_nodes.erase(it);
deba@57
  1448
        }
deba@57
  1449
      }
deba@57
  1450
kpeter@73
  1451
      void addEdge(const Edge& edge) {
alpar@209
  1452
        added_edges.push_front(edge);
deba@57
  1453
      }
kpeter@73
  1454
      void eraseEdge(const Edge& edge) {
alpar@209
  1455
        std::list<Edge>::iterator it =
kpeter@73
  1456
          std::find(added_edges.begin(), added_edges.end(), edge);
kpeter@73
  1457
        if (it == added_edges.end()) {
deba@57
  1458
          clear();
deba@57
  1459
          node_observer_proxy.detach();
deba@57
  1460
          throw EdgeNotifier::ImmediateDetach();
deba@57
  1461
        } else {
kpeter@73
  1462
          added_edges.erase(it);
kpeter@73
  1463
        }
deba@57
  1464
      }
deba@57
  1465
kpeter@73
  1466
      void attach(ListGraph &_graph) {
alpar@209
  1467
        graph = &_graph;
alpar@209
  1468
        node_observer_proxy.attach(graph->notifier(Node()));
kpeter@73
  1469
        edge_observer_proxy.attach(graph->notifier(Edge()));
deba@57
  1470
      }
alpar@209
  1471
deba@57
  1472
      void detach() {
alpar@209
  1473
        node_observer_proxy.detach();
alpar@209
  1474
        edge_observer_proxy.detach();
deba@57
  1475
      }
deba@57
  1476
deba@57
  1477
      bool attached() const {
deba@57
  1478
        return node_observer_proxy.attached();
deba@57
  1479
      }
deba@57
  1480
deba@57
  1481
      void clear() {
deba@57
  1482
        added_nodes.clear();
alpar@209
  1483
        added_edges.clear();
deba@57
  1484
      }
deba@57
  1485
deba@57
  1486
    public:
deba@57
  1487
deba@57
  1488
      /// \brief Default constructor.
deba@57
  1489
      ///
deba@57
  1490
      /// Default constructor.
deba@57
  1491
      /// To actually make a snapshot you must call save().
alpar@209
  1492
      Snapshot()
alpar@209
  1493
        : graph(0), node_observer_proxy(*this),
kpeter@73
  1494
          edge_observer_proxy(*this) {}
alpar@209
  1495
deba@57
  1496
      /// \brief Constructor that immediately makes a snapshot.
alpar@209
  1497
      ///
kpeter@73
  1498
      /// This constructor immediately makes a snapshot of the graph.
kpeter@73
  1499
      /// \param _graph The graph we make a snapshot of.
alpar@209
  1500
      Snapshot(ListGraph &_graph)
alpar@209
  1501
        : node_observer_proxy(*this),
kpeter@73
  1502
          edge_observer_proxy(*this) {
alpar@209
  1503
        attach(_graph);
deba@57
  1504
      }
alpar@209
  1505
deba@57
  1506
      /// \brief Make a snapshot.
deba@57
  1507
      ///
kpeter@73
  1508
      /// Make a snapshot of the graph.
deba@57
  1509
      ///
deba@57
  1510
      /// This function can be called more than once. In case of a repeated
deba@57
  1511
      /// call, the previous snapshot gets lost.
kpeter@73
  1512
      /// \param _graph The graph we make the snapshot of.
kpeter@73
  1513
      void save(ListGraph &_graph) {
deba@57
  1514
        if (attached()) {
deba@57
  1515
          detach();
deba@57
  1516
          clear();
deba@57
  1517
        }
kpeter@73
  1518
        attach(_graph);
deba@57
  1519
      }
alpar@209
  1520
deba@57
  1521
      /// \brief Undo the changes until the last snapshot.
alpar@209
  1522
      //
deba@57
  1523
      /// Undo the changes until the last snapshot created by save().
deba@57
  1524
      void restore() {
alpar@209
  1525
        detach();
alpar@209
  1526
        for(std::list<Edge>::iterator it = added_edges.begin();
kpeter@73
  1527
            it != added_edges.end(); ++it) {
alpar@209
  1528
          graph->erase(*it);
alpar@209
  1529
        }
alpar@209
  1530
        for(std::list<Node>::iterator it = added_nodes.begin();
deba@57
  1531
            it != added_nodes.end(); ++it) {
alpar@209
  1532
          graph->erase(*it);
alpar@209
  1533
        }
deba@57
  1534
        clear();
deba@57
  1535
      }
deba@57
  1536
deba@57
  1537
      /// \brief Gives back true when the snapshot is valid.
deba@57
  1538
      ///
deba@57
  1539
      /// Gives back true when the snapshot is valid.
deba@57
  1540
      bool valid() const {
deba@57
  1541
        return attached();
deba@57
  1542
      }
deba@57
  1543
    };
deba@57
  1544
  };
alpar@209
  1545
alpar@209
  1546
  /// @}
deba@57
  1547
} //namespace lemon
alpar@209
  1548
deba@57
  1549
deba@57
  1550
#endif