lemon/list_graph.h
author hegyi
Tue, 08 Apr 2008 11:39:40 +0000
changeset 2602 1c7790d9e025
parent 2498 290e43cddc1a
child 2618 6aa6fcaeaea5
permissions -rw-r--r--
Rel.07 NEWS - 3. round
alpar@948
     1
/* -*- C++ -*-
alpar@948
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@948
     8
 *
alpar@948
     9
 * Permission to use, modify and distribute this software is granted
alpar@948
    10
 * provided that this copyright notice appears in all copies. For
alpar@948
    11
 * precise terms see the accompanying LICENSE file.
alpar@948
    12
 *
alpar@948
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@948
    14
 * express or implied, and with no claim as to its suitability for any
alpar@948
    15
 * purpose.
alpar@948
    16
 *
alpar@948
    17
 */
alpar@395
    18
alpar@921
    19
#ifndef LEMON_LIST_GRAPH_H
alpar@921
    20
#define LEMON_LIST_GRAPH_H
alpar@395
    21
alpar@948
    22
///\ingroup graphs
alpar@948
    23
///\file
deba@2116
    24
///\brief ListGraph, ListUGraph classes.
alpar@948
    25
deba@2116
    26
#include <lemon/bits/base_extender.h>
deba@1791
    27
#include <lemon/bits/graph_extender.h>
deba@782
    28
deba@2116
    29
#include <lemon/error.h>
deba@2116
    30
deba@1979
    31
#include <vector>
alpar@1011
    32
#include <list>
deba@782
    33
alpar@921
    34
namespace lemon {
alpar@395
    35
klao@946
    36
  class ListGraphBase {
alpar@406
    37
alpar@949
    38
  protected:
klao@946
    39
    struct NodeT {
deba@1470
    40
      int first_in, first_out;
alpar@397
    41
      int prev, next;
alpar@395
    42
    };
klao@946
    43
 
klao@946
    44
    struct EdgeT {
alpar@986
    45
      int target, source;
alpar@397
    46
      int prev_in, prev_out;
alpar@397
    47
      int next_in, next_out;
alpar@395
    48
    };
alpar@395
    49
alpar@395
    50
    std::vector<NodeT> nodes;
klao@946
    51
alpar@397
    52
    int first_node;
klao@946
    53
alpar@397
    54
    int first_free_node;
klao@946
    55
alpar@395
    56
    std::vector<EdgeT> edges;
klao@946
    57
alpar@397
    58
    int first_free_edge;
alpar@395
    59
    
deba@782
    60
  public:
alpar@395
    61
    
klao@946
    62
    typedef ListGraphBase Graph;
alpar@397
    63
    
klao@946
    64
    class Node {
marci@975
    65
      friend class ListGraphBase;
klao@946
    66
    protected:
alpar@395
    67
klao@946
    68
      int id;
deba@2031
    69
      explicit Node(int pid) { id = pid;}
alpar@395
    70
klao@946
    71
    public:
klao@946
    72
      Node() {}
klao@946
    73
      Node (Invalid) { id = -1; }
klao@946
    74
      bool operator==(const Node& node) const {return id == node.id;}
klao@946
    75
      bool operator!=(const Node& node) const {return id != node.id;}
klao@946
    76
      bool operator<(const Node& node) const {return id < node.id;}
klao@946
    77
    };
deba@782
    78
klao@946
    79
    class Edge {
marci@975
    80
      friend class ListGraphBase;
klao@946
    81
    protected:
deba@782
    82
klao@946
    83
      int id;
deba@2031
    84
      explicit Edge(int pid) { id = pid;}
alpar@395
    85
klao@946
    86
    public:
klao@946
    87
      Edge() {}
klao@946
    88
      Edge (Invalid) { id = -1; }
klao@946
    89
      bool operator==(const Edge& edge) const {return id == edge.id;}
klao@946
    90
      bool operator!=(const Edge& edge) const {return id != edge.id;}
klao@946
    91
      bool operator<(const Edge& edge) const {return id < edge.id;}
klao@946
    92
    };
klao@946
    93
klao@946
    94
klao@946
    95
klao@946
    96
    ListGraphBase()
deba@782
    97
      : nodes(), first_node(-1),
deba@782
    98
	first_free_node(-1), edges(), first_free_edge(-1) {}
deba@782
    99
alpar@395
   100
    
deba@1791
   101
    int maxNodeId() const { return nodes.size()-1; } 
deba@1791
   102
    int maxEdgeId() const { return edges.size()-1; }
alpar@395
   103
deba@2031
   104
    Node source(Edge e) const { return Node(edges[e.id].source); }
deba@2031
   105
    Node target(Edge e) const { return Node(edges[e.id].target); }
alpar@395
   106
alpar@395
   107
klao@946
   108
    void first(Node& node) const { 
klao@946
   109
      node.id = first_node;
klao@946
   110
    }
klao@946
   111
klao@946
   112
    void next(Node& node) const {
klao@946
   113
      node.id = nodes[node.id].next;
klao@946
   114
    }
klao@946
   115
klao@946
   116
klao@946
   117
    void first(Edge& e) const { 
klao@946
   118
      int n;
klao@946
   119
      for(n = first_node; 
klao@946
   120
	  n!=-1 && nodes[n].first_in == -1; 
klao@946
   121
	  n = nodes[n].next);
klao@946
   122
      e.id = (n == -1) ? -1 : nodes[n].first_in;
klao@946
   123
    }
klao@946
   124
klao@946
   125
    void next(Edge& edge) const {
klao@946
   126
      if (edges[edge.id].next_in != -1) {
klao@946
   127
	edge.id = edges[edge.id].next_in;
klao@946
   128
      } else {
klao@946
   129
	int n;
alpar@986
   130
	for(n = nodes[edges[edge.id].target].next;
klao@946
   131
	  n!=-1 && nodes[n].first_in == -1; 
klao@946
   132
	  n = nodes[n].next);
klao@946
   133
	edge.id = (n == -1) ? -1 : nodes[n].first_in;
klao@946
   134
      }      
klao@946
   135
    }
klao@946
   136
klao@946
   137
    void firstOut(Edge &e, const Node& v) const {
klao@946
   138
      e.id = nodes[v.id].first_out;
klao@946
   139
    }
klao@946
   140
    void nextOut(Edge &e) const {
klao@946
   141
      e.id=edges[e.id].next_out;
klao@946
   142
    }
klao@946
   143
klao@946
   144
    void firstIn(Edge &e, const Node& v) const {
klao@946
   145
      e.id = nodes[v.id].first_in;
klao@946
   146
    }
klao@946
   147
    void nextIn(Edge &e) const {
klao@946
   148
      e.id=edges[e.id].next_in;
klao@946
   149
    }
klao@946
   150
alpar@813
   151
    
klao@946
   152
    static int id(Node v) { return v.id; }
klao@946
   153
    static int id(Edge e) { return e.id; }
alpar@395
   154
deba@1791
   155
    static Node nodeFromId(int id) { return Node(id);}
deba@1791
   156
    static Edge edgeFromId(int id) { return Edge(id);}
deba@1106
   157
klao@946
   158
    Node addNode() {     
alpar@397
   159
      int n;
alpar@397
   160
      
klao@946
   161
      if(first_free_node==-1) {
klao@946
   162
	n = nodes.size();
klao@946
   163
	nodes.push_back(NodeT());
klao@946
   164
      } else {
alpar@397
   165
	n = first_free_node;
alpar@397
   166
	first_free_node = nodes[n].next;
alpar@397
   167
      }
alpar@397
   168
      
alpar@397
   169
      nodes[n].next = first_node;
alpar@397
   170
      if(first_node != -1) nodes[first_node].prev = n;
alpar@397
   171
      first_node = n;
alpar@397
   172
      nodes[n].prev = -1;
alpar@397
   173
      
alpar@397
   174
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@397
   175
      
klao@946
   176
      return Node(n);
alpar@395
   177
    }
alpar@395
   178
    
alpar@395
   179
    Edge addEdge(Node u, Node v) {
klao@946
   180
      int n;      
klao@946
   181
klao@946
   182
      if (first_free_edge == -1) {
klao@946
   183
	n = edges.size();
klao@946
   184
	edges.push_back(EdgeT());
klao@946
   185
      } else {
alpar@397
   186
	n = first_free_edge;
alpar@397
   187
	first_free_edge = edges[n].next_in;
alpar@397
   188
      }
alpar@397
   189
      
alpar@986
   190
      edges[n].source = u.id; 
alpar@986
   191
      edges[n].target = v.id;
alpar@395
   192
klao@946
   193
      edges[n].next_out = nodes[u.id].first_out;
klao@946
   194
      if(nodes[u.id].first_out != -1) {
klao@946
   195
	edges[nodes[u.id].first_out].prev_out = n;
klao@946
   196
      }
klao@946
   197
      
klao@946
   198
      edges[n].next_in = nodes[v.id].first_in;
klao@946
   199
      if(nodes[v.id].first_in != -1) {
klao@946
   200
	edges[nodes[v.id].first_in].prev_in = n;
klao@946
   201
      }
klao@946
   202
      
alpar@397
   203
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@397
   204
	
klao@946
   205
      nodes[u.id].first_out = nodes[v.id].first_in = n;
alpar@397
   206
klao@946
   207
      return Edge(n);
alpar@395
   208
    }
alpar@774
   209
    
klao@946
   210
    void erase(const Node& node) {
klao@946
   211
      int n = node.id;
klao@946
   212
      
klao@946
   213
      if(nodes[n].next != -1) {
klao@946
   214
	nodes[nodes[n].next].prev = nodes[n].prev;
klao@946
   215
      }
klao@946
   216
      
klao@946
   217
      if(nodes[n].prev != -1) {
klao@946
   218
	nodes[nodes[n].prev].next = nodes[n].next;
klao@946
   219
      } else {
klao@946
   220
	first_node = nodes[n].next;
klao@946
   221
      }
klao@946
   222
      
klao@946
   223
      nodes[n].next = first_free_node;
klao@946
   224
      first_free_node = n;
alpar@395
   225
alpar@774
   226
    }
alpar@774
   227
    
klao@946
   228
    void erase(const Edge& edge) {
klao@946
   229
      int n = edge.id;
alpar@397
   230
      
klao@946
   231
      if(edges[n].next_in!=-1) {
alpar@397
   232
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
klao@946
   233
      }
klao@946
   234
klao@946
   235
      if(edges[n].prev_in!=-1) {
alpar@397
   236
	edges[edges[n].prev_in].next_in = edges[n].next_in;
klao@946
   237
      } else {
alpar@986
   238
	nodes[edges[n].target].first_in = edges[n].next_in;
klao@946
   239
      }
klao@946
   240
alpar@397
   241
      
klao@946
   242
      if(edges[n].next_out!=-1) {
alpar@397
   243
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
klao@946
   244
      } 
klao@946
   245
klao@946
   246
      if(edges[n].prev_out!=-1) {
alpar@397
   247
	edges[edges[n].prev_out].next_out = edges[n].next_out;
klao@946
   248
      } else {
alpar@986
   249
	nodes[edges[n].source].first_out = edges[n].next_out;
klao@946
   250
      }
alpar@397
   251
      
alpar@397
   252
      edges[n].next_in = first_free_edge;
alpar@695
   253
      first_free_edge = n;      
alpar@397
   254
alpar@397
   255
    }
alpar@397
   256
alpar@397
   257
    void clear() {
deba@782
   258
      edges.clear();
deba@782
   259
      nodes.clear();
klao@946
   260
      first_node = first_free_node = first_free_edge = -1;
deba@937
   261
    }
deba@937
   262
alpar@949
   263
  protected:
deba@2111
   264
    void changeTarget(Edge e, Node n) 
alpar@949
   265
    {
alpar@949
   266
      if(edges[e.id].next_in != -1)
alpar@949
   267
	edges[edges[e.id].next_in].prev_in = edges[e.id].prev_in;
alpar@949
   268
      if(edges[e.id].prev_in != -1)
alpar@949
   269
	edges[edges[e.id].prev_in].next_in = edges[e.id].next_in;
alpar@986
   270
      else nodes[edges[e.id].target].first_in = edges[e.id].next_in;
deba@1702
   271
      if (nodes[n.id].first_in != -1) {
deba@1702
   272
	edges[nodes[n.id].first_in].prev_in = e.id;
deba@1702
   273
      }
alpar@986
   274
      edges[e.id].target = n.id;
alpar@949
   275
      edges[e.id].prev_in = -1;
alpar@949
   276
      edges[e.id].next_in = nodes[n.id].first_in;
alpar@949
   277
      nodes[n.id].first_in = e.id;
alpar@949
   278
    }
deba@2111
   279
    void changeSource(Edge e, Node n) 
alpar@949
   280
    {
alpar@949
   281
      if(edges[e.id].next_out != -1)
alpar@949
   282
	edges[edges[e.id].next_out].prev_out = edges[e.id].prev_out;
alpar@949
   283
      if(edges[e.id].prev_out != -1)
alpar@949
   284
	edges[edges[e.id].prev_out].next_out = edges[e.id].next_out;
alpar@986
   285
      else nodes[edges[e.id].source].first_out = edges[e.id].next_out;
deba@1702
   286
      if (nodes[n.id].first_out != -1) {
deba@1702
   287
	edges[nodes[n.id].first_out].prev_out = e.id;
deba@1702
   288
      }
alpar@986
   289
      edges[e.id].source = n.id;
alpar@949
   290
      edges[e.id].prev_out = -1;
alpar@949
   291
      edges[e.id].next_out = nodes[n.id].first_out;
alpar@949
   292
      nodes[n.id].first_out = e.id;
alpar@949
   293
    }
alpar@949
   294
alpar@919
   295
  };
deba@909
   296
deba@1979
   297
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
alpar@400
   298
deba@2116
   299
  /// \addtogroup graphs
deba@2116
   300
  /// @{
alpar@400
   301
alpar@948
   302
  ///A list graph class.
alpar@400
   303
alpar@2117
   304
  ///This is a simple and fast graph implementation.
alpar@948
   305
  ///
alpar@2260
   306
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
deba@2111
   307
  ///also provides several additional useful extra functionalities.
deba@2111
   308
  ///The most of the member functions and nested classes are
deba@2111
   309
  ///documented only in the concept class.
alpar@2256
   310
  ///
alpar@2256
   311
  ///An important extra feature of this graph implementation is that
alpar@2260
   312
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
alpar@2256
   313
  ///
alpar@2260
   314
  ///\sa concepts::Graph.
deba@782
   315
deba@1999
   316
  class ListGraph : public ExtendedListGraphBase {
alpar@2128
   317
  private:
alpar@2128
   318
    ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
alpar@2128
   319
    
alpar@2128
   320
    ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
alpar@2128
   321
    ///
alpar@2128
   322
    ListGraph(const ListGraph &) :ExtendedListGraphBase() {};
alpar@2132
   323
    ///\brief Assignment of ListGraph to another one is \e not allowed.
alpar@2128
   324
    ///Use GraphCopy() instead.
alpar@2128
   325
alpar@2132
   326
    ///Assignment of ListGraph to another one is \e not allowed.
alpar@2128
   327
    ///Use GraphCopy() instead.
alpar@2128
   328
    void operator=(const ListGraph &) {}
alpar@948
   329
  public:
deba@1999
   330
deba@1999
   331
    typedef ExtendedListGraphBase Parent;
deba@1999
   332
alpar@2128
   333
    /// Constructor
alpar@2128
   334
    
alpar@2128
   335
    /// Constructor.
alpar@2128
   336
    ///
alpar@2128
   337
    ListGraph() {}
alpar@2128
   338
deba@2111
   339
    ///Add a new node to the graph.
deba@2111
   340
    
deba@2111
   341
    /// \return the new node.
deba@2111
   342
    ///
deba@2111
   343
    Node addNode() { return Parent::addNode(); }
deba@2111
   344
deba@2111
   345
    ///Add a new edge to the graph.
deba@2111
   346
    
deba@2111
   347
    ///Add a new edge to the graph with source node \c s
deba@2111
   348
    ///and target node \c t.
deba@2111
   349
    ///\return the new edge.
deba@2111
   350
    Edge addEdge(const Node& s, const Node& t) { 
deba@2111
   351
      return Parent::addEdge(s, t); 
deba@2111
   352
    }
deba@2111
   353
alpar@1546
   354
    /// Changes the target of \c e to \c n
alpar@948
   355
alpar@1546
   356
    /// Changes the target of \c e to \c n
alpar@948
   357
    ///
deba@2160
   358
    ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s referencing
deba@2114
   359
    ///the changed edge remain valid. However <tt>InEdgeIt</tt>s are
deba@2114
   360
    ///invalidated.
alpar@2123
   361
    ///\warning This functionality cannot be used together with the Snapshot
alpar@2123
   362
    ///feature.
deba@1718
   363
    void changeTarget(Edge e, Node n) { 
deba@2111
   364
      Parent::changeTarget(e,n); 
deba@1718
   365
    }
alpar@1546
   366
    /// Changes the source of \c e to \c n
alpar@948
   367
alpar@1546
   368
    /// Changes the source of \c e to \c n
alpar@948
   369
    ///
deba@2160
   370
    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
deba@2114
   371
    ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
deba@2114
   372
    ///invalidated.
alpar@2123
   373
    ///\warning This functionality cannot be used together with the Snapshot
alpar@2123
   374
    ///feature.
deba@1718
   375
    void changeSource(Edge e, Node n) { 
deba@2111
   376
      Parent::changeSource(e,n);
deba@1718
   377
    }
alpar@949
   378
alpar@1010
   379
    /// Invert the direction of an edge.
alpar@1010
   380
deba@2160
   381
    ///\note The <tt>EdgeIt</tt>s referencing the changed edge remain
deba@2114
   382
    ///valid. However <tt>OutEdgeIt</tt>s and <tt>InEdgeIt</tt>s are
deba@2114
   383
    ///invalidated.
alpar@2123
   384
    ///\warning This functionality cannot be used together with the Snapshot
alpar@2123
   385
    ///feature.
alpar@1010
   386
    void reverseEdge(Edge e) {
alpar@1010
   387
      Node t=target(e);
deba@2111
   388
      changeTarget(e,source(e));
deba@2111
   389
      changeSource(e,t);
alpar@1010
   390
    }
alpar@1010
   391
deba@2456
   392
    /// Using this it is possible to avoid the superfluous memory
deba@2456
   393
    /// allocation: if you know that the graph you want to build will
deba@2456
   394
    /// be very large (e.g. it will contain millions of nodes and/or edges)
deba@2456
   395
    /// then it is worth reserving space for this amount before starting
deba@2456
   396
    /// to build the graph.
deba@2456
   397
    /// \sa reserveEdge
deba@2107
   398
    void reserveNode(int n) { nodes.reserve(n); };
deba@2107
   399
deba@2111
   400
    /// \brief Using this it is possible to avoid the superfluous memory
deba@2111
   401
    /// allocation.
deba@2107
   402
deba@2456
   403
    /// Using this it is possible to avoid the superfluous memory
deba@2456
   404
    /// allocation: if you know that the graph you want to build will
deba@2456
   405
    /// be very large (e.g. it will contain millions of nodes and/or edges)
deba@2456
   406
    /// then it is worth reserving space for this amount before starting
deba@2456
   407
    /// to build the graph.
deba@2456
   408
    /// \sa reserveNode
deba@2456
   409
    void reserveEdge(int m) { edges.reserve(m); };
deba@2107
   410
alpar@1010
   411
    ///Contract two nodes.
alpar@1010
   412
alpar@1010
   413
    ///This function contracts two nodes.
alpar@1010
   414
    ///
alpar@1010
   415
    ///Node \p b will be removed but instead of deleting
athos@2102
   416
    ///incident edges, they will be joined to \p a.
alpar@1010
   417
    ///The last parameter \p r controls whether to remove loops. \c true
alpar@1010
   418
    ///means that loops will be removed.
alpar@1010
   419
    ///
deba@2160
   420
    ///\note The <tt>EdgeIt</tt>s
alpar@1281
   421
    ///referencing a moved edge remain
deba@2160
   422
    ///valid. However <tt>InEdgeIt</tt>s and <tt>OutEdgeIt</tt>s
alpar@1010
   423
    ///may be invalidated.
alpar@2123
   424
    ///\warning This functionality cannot be used together with the Snapshot
alpar@2123
   425
    ///feature.
deba@1718
   426
    void contract(Node a, Node b, bool r = true) 
alpar@1010
   427
    {
alpar@1010
   428
      for(OutEdgeIt e(*this,b);e!=INVALID;) {
alpar@1010
   429
	OutEdgeIt f=e;
alpar@1010
   430
	++f;
alpar@1010
   431
	if(r && target(e)==a) erase(e);
alpar@1546
   432
	else changeSource(e,a);
alpar@1010
   433
	e=f;
alpar@1010
   434
      }
alpar@1010
   435
      for(InEdgeIt e(*this,b);e!=INVALID;) {
alpar@1010
   436
	InEdgeIt f=e;
alpar@1010
   437
	++f;
alpar@1010
   438
	if(r && source(e)==a) erase(e);
alpar@1546
   439
	else changeTarget(e,a);
alpar@1010
   440
	e=f;
alpar@1010
   441
      }
alpar@1010
   442
      erase(b);
alpar@1010
   443
    }
alpar@1011
   444
alpar@1281
   445
    ///Split a node.
alpar@1011
   446
alpar@1284
   447
    ///This function splits a node. First a new node is added to the graph,
alpar@1284
   448
    ///then the source of each outgoing edge of \c n is moved to this new node.
alpar@1281
   449
    ///If \c connect is \c true (this is the default value), then a new edge
alpar@1281
   450
    ///from \c n to the newly created node is also added.
alpar@1281
   451
    ///\return The newly created node.
alpar@1281
   452
    ///
deba@2160
   453
    ///\note The <tt>EdgeIt</tt>s referencing a moved edge remain
deba@2160
   454
    ///valid. However <tt>InEdgeIt</tt>s and <tt>OutEdgeIt</tt>s may
deba@2160
   455
    ///be invalidated.  
deba@2160
   456
    ///
deba@2160
   457
    ///\warning This functionality cannot be used together with the
deba@2160
   458
    ///Snapshot feature.  \todo It could be implemented in a bit
deba@2160
   459
    ///faster way.
deba@2114
   460
    Node split(Node n, bool connect = true) {
alpar@1281
   461
      Node b = addNode();
alpar@1281
   462
      for(OutEdgeIt e(*this,n);e!=INVALID;) {
alpar@1281
   463
 	OutEdgeIt f=e;
alpar@1281
   464
	++f;
alpar@1546
   465
	changeSource(e,b);
alpar@1281
   466
	e=f;
alpar@1281
   467
      }
deba@2114
   468
      if (connect) addEdge(n,b);
alpar@1281
   469
      return b;
alpar@1281
   470
    }
alpar@1281
   471
      
alpar@1812
   472
    ///Split an edge.
alpar@1812
   473
athos@2102
   474
    ///This function splits an edge. First a new node \c b is added to
athos@2102
   475
    ///the graph, then the original edge is re-targeted to \c
athos@2102
   476
    ///b. Finally an edge from \c b to the original target is added.
athos@2102
   477
    ///\return The newly created node.  
athos@2102
   478
    ///\warning This functionality
athos@2102
   479
    ///cannot be used together with the Snapshot feature.
deba@2114
   480
    Node split(Edge e) {
alpar@1812
   481
      Node b = addNode();
alpar@1812
   482
      addEdge(b,target(e));
alpar@1812
   483
      changeTarget(e,b);
alpar@1812
   484
      return b;
alpar@1812
   485
    }
alpar@1812
   486
      
deba@2114
   487
    /// \brief Class to make a snapshot of the graph and restore
deba@2114
   488
    /// to it later.
alpar@1011
   489
    ///
deba@2114
   490
    /// Class to make a snapshot of the graph and to restore it
deba@2114
   491
    /// later.
alpar@1011
   492
    ///
deba@2114
   493
    /// The newly added nodes and edges can be removed using the
deba@2114
   494
    /// restore() function.
deba@2114
   495
    ///
deba@2189
   496
    /// \warning Edge and node deletions cannot be restored. This
deba@2189
   497
    /// events invalidate the snapshot. 
deba@2114
   498
    class Snapshot {
deba@1999
   499
    protected:
deba@2114
   500
deba@2114
   501
      typedef Parent::NodeNotifier NodeNotifier;
deba@2114
   502
deba@2114
   503
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
deba@2114
   504
      public:
deba@2114
   505
deba@2114
   506
        NodeObserverProxy(Snapshot& _snapshot)
deba@2114
   507
          : snapshot(_snapshot) {}
deba@2114
   508
deba@2114
   509
        using NodeNotifier::ObserverBase::attach;
deba@2114
   510
        using NodeNotifier::ObserverBase::detach;
deba@2114
   511
        using NodeNotifier::ObserverBase::attached;
deba@2114
   512
        
deba@2114
   513
      protected:
deba@2114
   514
        
deba@2114
   515
        virtual void add(const Node& node) {
deba@2114
   516
          snapshot.addNode(node);
deba@2114
   517
        }
deba@2114
   518
        virtual void add(const std::vector<Node>& nodes) {
deba@2114
   519
          for (int i = nodes.size() - 1; i >= 0; ++i) {
deba@2114
   520
            snapshot.addNode(nodes[i]);
deba@2114
   521
          }
deba@2114
   522
        }
deba@2114
   523
        virtual void erase(const Node& node) {
deba@2114
   524
          snapshot.eraseNode(node);
deba@2114
   525
        }
deba@2114
   526
        virtual void erase(const std::vector<Node>& nodes) {
deba@2386
   527
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@2189
   528
            snapshot.eraseNode(nodes[i]);
deba@2114
   529
          }
deba@2114
   530
        }
deba@2114
   531
        virtual void build() {
deba@2114
   532
          Node node;
deba@2114
   533
          std::vector<Node> nodes;
deba@2386
   534
          for (notifier()->first(node); node != INVALID; 
deba@2386
   535
               notifier()->next(node)) {
deba@2114
   536
            nodes.push_back(node);
deba@2114
   537
          }
deba@2114
   538
          for (int i = nodes.size() - 1; i >= 0; --i) {
deba@2114
   539
            snapshot.addNode(nodes[i]);
deba@2114
   540
          }
deba@2114
   541
        }
deba@2114
   542
        virtual void clear() {
deba@2114
   543
          Node node;
deba@2386
   544
          for (notifier()->first(node); node != INVALID; 
deba@2386
   545
               notifier()->next(node)) {
deba@2189
   546
            snapshot.eraseNode(node);
deba@2114
   547
          }
deba@2114
   548
        }
deba@2114
   549
deba@2114
   550
        Snapshot& snapshot;
deba@2114
   551
      };
deba@2114
   552
deba@2114
   553
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
deba@2114
   554
      public:
deba@2114
   555
deba@2114
   556
        EdgeObserverProxy(Snapshot& _snapshot)
deba@2114
   557
          : snapshot(_snapshot) {}
deba@2114
   558
deba@2114
   559
        using EdgeNotifier::ObserverBase::attach;
deba@2114
   560
        using EdgeNotifier::ObserverBase::detach;
deba@2114
   561
        using EdgeNotifier::ObserverBase::attached;
deba@2114
   562
        
deba@2114
   563
      protected:
deba@2114
   564
deba@2114
   565
        virtual void add(const Edge& edge) {
deba@2114
   566
          snapshot.addEdge(edge);
deba@2114
   567
        }
deba@2114
   568
        virtual void add(const std::vector<Edge>& edges) {
deba@2114
   569
          for (int i = edges.size() - 1; i >= 0; ++i) {
deba@2114
   570
            snapshot.addEdge(edges[i]);
deba@2114
   571
          }
deba@2114
   572
        }
deba@2114
   573
        virtual void erase(const Edge& edge) {
deba@2114
   574
          snapshot.eraseEdge(edge);
deba@2114
   575
        }
deba@2114
   576
        virtual void erase(const std::vector<Edge>& edges) {
deba@2386
   577
          for (int i = 0; i < int(edges.size()); ++i) {
deba@2189
   578
            snapshot.eraseEdge(edges[i]);
deba@2114
   579
          }
deba@2114
   580
        }
deba@2114
   581
        virtual void build() {
deba@2114
   582
          Edge edge;
deba@2114
   583
          std::vector<Edge> edges;
deba@2386
   584
          for (notifier()->first(edge); edge != INVALID; 
deba@2386
   585
               notifier()->next(edge)) {
deba@2114
   586
            edges.push_back(edge);
deba@2114
   587
          }
deba@2114
   588
          for (int i = edges.size() - 1; i >= 0; --i) {
deba@2114
   589
            snapshot.addEdge(edges[i]);
deba@2114
   590
          }
deba@2114
   591
        }
deba@2114
   592
        virtual void clear() {
deba@2114
   593
          Edge edge;
deba@2386
   594
          for (notifier()->first(edge); edge != INVALID; 
deba@2386
   595
               notifier()->next(edge)) {
deba@2189
   596
            snapshot.eraseEdge(edge);
deba@2114
   597
          }
deba@2114
   598
        }
deba@2114
   599
deba@2114
   600
        Snapshot& snapshot;
deba@2114
   601
      };
alpar@1011
   602
      
deba@2114
   603
      ListGraph *graph;
deba@2114
   604
deba@2114
   605
      NodeObserverProxy node_observer_proxy;
deba@2114
   606
      EdgeObserverProxy edge_observer_proxy;
deba@2114
   607
alpar@1011
   608
      std::list<Node> added_nodes;
alpar@1011
   609
      std::list<Edge> added_edges;
deba@2114
   610
deba@2114
   611
deba@2114
   612
      void addNode(const Node& node) {
deba@2114
   613
        added_nodes.push_front(node);        
alpar@1011
   614
      }
deba@2189
   615
      void eraseNode(const Node& node) {
deba@2114
   616
        std::list<Node>::iterator it = 
deba@2114
   617
          std::find(added_nodes.begin(), added_nodes.end(), node);
deba@2114
   618
        if (it == added_nodes.end()) {
deba@2114
   619
          clear();
deba@2189
   620
          edge_observer_proxy.detach();
deba@2189
   621
          throw NodeNotifier::ImmediateDetach();
deba@2114
   622
        } else {
deba@2114
   623
          added_nodes.erase(it);
deba@2114
   624
        }
alpar@1011
   625
      }
alpar@1011
   626
deba@2114
   627
      void addEdge(const Edge& edge) {
deba@2114
   628
        added_edges.push_front(edge);        
deba@2114
   629
      }
deba@2189
   630
      void eraseEdge(const Edge& edge) {
deba@2114
   631
        std::list<Edge>::iterator it = 
deba@2114
   632
          std::find(added_edges.begin(), added_edges.end(), edge);
deba@2114
   633
        if (it == added_edges.end()) {
deba@2114
   634
          clear();
deba@2189
   635
          node_observer_proxy.detach(); 
deba@2189
   636
          throw EdgeNotifier::ImmediateDetach();
deba@2114
   637
        } else {
deba@2114
   638
          added_edges.erase(it);
deba@2114
   639
        }        
deba@2114
   640
      }
alpar@1457
   641
deba@2114
   642
      void attach(ListGraph &_graph) {
deba@2114
   643
	graph = &_graph;
deba@2381
   644
	node_observer_proxy.attach(graph->notifier(Node()));
deba@2381
   645
        edge_observer_proxy.attach(graph->notifier(Edge()));
alpar@1011
   646
      }
alpar@1011
   647
            
deba@2114
   648
      void detach() {
deba@2114
   649
	node_observer_proxy.detach();
deba@2114
   650
	edge_observer_proxy.detach();
deba@2114
   651
      }
deba@2114
   652
deba@2189
   653
      bool attached() const {
deba@2189
   654
        return node_observer_proxy.attached();
deba@2189
   655
      }
deba@2189
   656
deba@2114
   657
      void clear() {
deba@2114
   658
        added_nodes.clear();
deba@2114
   659
        added_edges.clear();        
alpar@1011
   660
      }
deba@1774
   661
alpar@1011
   662
    public:
deba@2114
   663
deba@2160
   664
      /// \brief Default constructor.
deba@2114
   665
      ///
deba@2114
   666
      /// Default constructor.
deba@2114
   667
      /// To actually make a snapshot you must call save().
deba@2114
   668
      Snapshot() 
deba@2114
   669
        : graph(0), node_observer_proxy(*this), 
deba@2114
   670
          edge_observer_proxy(*this) {}
alpar@1011
   671
      
deba@2114
   672
      /// \brief Constructor that immediately makes a snapshot.
deba@2114
   673
      ///      
deba@2114
   674
      /// This constructor immediately makes a snapshot of the graph.
deba@2114
   675
      /// \param _graph The graph we make a snapshot of.
deba@2114
   676
      Snapshot(ListGraph &_graph) 
deba@2114
   677
        : node_observer_proxy(*this), 
deba@2114
   678
          edge_observer_proxy(*this) {
deba@2114
   679
	attach(_graph);
alpar@1011
   680
      }
alpar@1011
   681
      
deba@2114
   682
      /// \brief Make a snapshot.
alpar@1011
   683
      ///
deba@2114
   684
      /// Make a snapshot of the graph.
deba@2114
   685
      ///
deba@2114
   686
      /// This function can be called more than once. In case of a repeated
deba@2114
   687
      /// call, the previous snapshot gets lost.
deba@2114
   688
      /// \param _graph The graph we make the snapshot of.
deba@2114
   689
      void save(ListGraph &_graph) {
deba@2189
   690
        if (attached()) {
deba@2189
   691
          detach();
deba@2189
   692
          clear();
deba@2189
   693
        }
deba@2114
   694
        attach(_graph);
alpar@1011
   695
      }
alpar@1011
   696
      
deba@2114
   697
      /// \brief Undo the changes until the last snapshot.
deba@2114
   698
      // 
alpar@2123
   699
      /// Undo the changes until the last snapshot created by save().
alpar@1011
   700
      void restore() {
deba@2114
   701
	detach();
deba@2189
   702
	for(std::list<Edge>::iterator it = added_edges.begin(); 
deba@2189
   703
            it != added_edges.end(); ++it) {
deba@2189
   704
	  graph->erase(*it);
alpar@1011
   705
	}
deba@2189
   706
	for(std::list<Node>::iterator it = added_nodes.begin(); 
deba@2189
   707
            it != added_nodes.end(); ++it) {
deba@2189
   708
	  graph->erase(*it);
alpar@1011
   709
	}
deba@2189
   710
        clear();
alpar@1011
   711
      }
deba@2114
   712
deba@2114
   713
      /// \brief Gives back true when the snapshot is valid.
deba@2114
   714
      ///
deba@2114
   715
      /// Gives back true when the snapshot is valid.
deba@2114
   716
      bool valid() const {
deba@2189
   717
        return attached();
deba@2114
   718
      }
alpar@1011
   719
    };
alpar@1011
   720
    
alpar@949
   721
  };
klao@1034
   722
deba@2116
   723
  ///@}
deba@2116
   724
deba@2338
   725
  class ListUGraphBase {
deba@2116
   726
deba@2338
   727
  protected:
deba@2338
   728
deba@2338
   729
    struct NodeT {
deba@2338
   730
      int first_out;
deba@2338
   731
      int prev, next;
deba@2338
   732
    };
deba@2338
   733
 
deba@2338
   734
    struct EdgeT {
deba@2338
   735
      int target;
deba@2338
   736
      int prev_out, next_out;
deba@2338
   737
    };
deba@2338
   738
deba@2338
   739
    std::vector<NodeT> nodes;
deba@2338
   740
deba@2338
   741
    int first_node;
deba@2338
   742
deba@2338
   743
    int first_free_node;
deba@2338
   744
deba@2338
   745
    std::vector<EdgeT> edges;
deba@2338
   746
deba@2338
   747
    int first_free_edge;
deba@2338
   748
    
deba@2338
   749
  public:
deba@2338
   750
    
deba@2338
   751
    typedef ListUGraphBase Graph;
deba@2343
   752
deba@2343
   753
    class Node;
deba@2343
   754
    class Edge;
deba@2343
   755
    class UEdge;
deba@2338
   756
    
deba@2338
   757
    class Node {
deba@2338
   758
      friend class ListUGraphBase;
deba@2338
   759
    protected:
deba@2338
   760
deba@2338
   761
      int id;
deba@2338
   762
      explicit Node(int pid) { id = pid;}
deba@2338
   763
deba@2338
   764
    public:
deba@2338
   765
      Node() {}
deba@2338
   766
      Node (Invalid) { id = -1; }
deba@2338
   767
      bool operator==(const Node& node) const {return id == node.id;}
deba@2338
   768
      bool operator!=(const Node& node) const {return id != node.id;}
deba@2338
   769
      bool operator<(const Node& node) const {return id < node.id;}
deba@2338
   770
    };
deba@2338
   771
deba@2338
   772
    class UEdge {
deba@2338
   773
      friend class ListUGraphBase;
deba@2338
   774
    protected:
deba@2338
   775
deba@2338
   776
      int id;
deba@2338
   777
      explicit UEdge(int pid) { id = pid;}
deba@2338
   778
deba@2338
   779
    public:
deba@2338
   780
      UEdge() {}
deba@2338
   781
      UEdge (Invalid) { id = -1; }
deba@2338
   782
      bool operator==(const UEdge& edge) const {return id == edge.id;}
deba@2338
   783
      bool operator!=(const UEdge& edge) const {return id != edge.id;}
deba@2338
   784
      bool operator<(const UEdge& edge) const {return id < edge.id;}
deba@2338
   785
    };
deba@2338
   786
deba@2338
   787
    class Edge {
deba@2338
   788
      friend class ListUGraphBase;
deba@2338
   789
    protected:
deba@2338
   790
deba@2338
   791
      int id;
deba@2338
   792
      explicit Edge(int pid) { id = pid;}
deba@2338
   793
deba@2338
   794
    public:
deba@2343
   795
      operator UEdge() const { return uEdgeFromId(id / 2); }
deba@2338
   796
deba@2338
   797
      Edge() {}
deba@2338
   798
      Edge (Invalid) { id = -1; }
deba@2338
   799
      bool operator==(const Edge& edge) const {return id == edge.id;}
deba@2338
   800
      bool operator!=(const Edge& edge) const {return id != edge.id;}
deba@2338
   801
      bool operator<(const Edge& edge) const {return id < edge.id;}
deba@2338
   802
    };
deba@2338
   803
deba@2338
   804
deba@2338
   805
deba@2338
   806
    ListUGraphBase()
deba@2338
   807
      : nodes(), first_node(-1),
deba@2338
   808
	first_free_node(-1), edges(), first_free_edge(-1) {}
deba@2338
   809
deba@2338
   810
    
deba@2338
   811
    int maxNodeId() const { return nodes.size()-1; } 
deba@2338
   812
    int maxUEdgeId() const { return edges.size() / 2 - 1; }
deba@2338
   813
    int maxEdgeId() const { return edges.size()-1; }
deba@2338
   814
deba@2338
   815
    Node source(Edge e) const { return Node(edges[e.id ^ 1].target); }
deba@2338
   816
    Node target(Edge e) const { return Node(edges[e.id].target); }
deba@2338
   817
deba@2338
   818
    Node source(UEdge e) const { return Node(edges[2 * e.id].target); }
deba@2338
   819
    Node target(UEdge e) const { return Node(edges[2 * e.id + 1].target); }
deba@2338
   820
deba@2338
   821
    static bool direction(Edge e) {
deba@2338
   822
      return (e.id & 1) == 1;
deba@2338
   823
    }
deba@2338
   824
deba@2338
   825
    static Edge direct(UEdge e, bool d) {
deba@2338
   826
      return Edge(e.id * 2 + (d ? 1 : 0));
deba@2338
   827
    }
deba@2338
   828
deba@2338
   829
    void first(Node& node) const { 
deba@2338
   830
      node.id = first_node;
deba@2338
   831
    }
deba@2338
   832
deba@2338
   833
    void next(Node& node) const {
deba@2338
   834
      node.id = nodes[node.id].next;
deba@2338
   835
    }
deba@2338
   836
deba@2338
   837
    void first(Edge& e) const { 
deba@2338
   838
      int n = first_node;
deba@2338
   839
      while (n != -1 && nodes[n].first_out == -1) {
deba@2338
   840
        n = nodes[n].next;
deba@2338
   841
      }
deba@2338
   842
      e.id = (n == -1) ? -1 : nodes[n].first_out;
deba@2338
   843
    }
deba@2338
   844
deba@2338
   845
    void next(Edge& e) const {
deba@2338
   846
      if (edges[e.id].next_out != -1) {
deba@2338
   847
	e.id = edges[e.id].next_out;
deba@2338
   848
      } else {
deba@2338
   849
	int n = nodes[edges[e.id ^ 1].target].next;
deba@2338
   850
        while(n != -1 && nodes[n].first_out == -1) {
deba@2338
   851
          n = nodes[n].next;
deba@2338
   852
        }
deba@2338
   853
	e.id = (n == -1) ? -1 : nodes[n].first_out;
deba@2338
   854
      }      
deba@2338
   855
    }
deba@2338
   856
deba@2338
   857
    void first(UEdge& e) const { 
deba@2338
   858
      int n = first_node;
deba@2338
   859
      while (n != -1) {
deba@2338
   860
        e.id = nodes[n].first_out;
deba@2338
   861
        while ((e.id & 1) != 1) {
deba@2338
   862
          e.id = edges[e.id].next_out;
deba@2338
   863
        }
deba@2338
   864
        if (e.id != -1) {
deba@2338
   865
          e.id /= 2;
deba@2338
   866
          return;
deba@2338
   867
        } 
deba@2338
   868
        n = nodes[n].next;
deba@2338
   869
      }
deba@2338
   870
      e.id = -1;
deba@2338
   871
    }
deba@2338
   872
deba@2338
   873
    void next(UEdge& e) const {
deba@2338
   874
      int n = edges[e.id * 2].target;
deba@2338
   875
      e.id = edges[(e.id * 2) | 1].next_out;
deba@2338
   876
      while ((e.id & 1) != 1) {
deba@2338
   877
        e.id = edges[e.id].next_out;
deba@2338
   878
      }
deba@2338
   879
      if (e.id != -1) {
deba@2338
   880
        e.id /= 2;
deba@2338
   881
        return;
deba@2338
   882
      } 
deba@2338
   883
      n = nodes[n].next;
deba@2338
   884
      while (n != -1) {
deba@2338
   885
        e.id = nodes[n].first_out;
deba@2338
   886
        while ((e.id & 1) != 1) {
deba@2338
   887
          e.id = edges[e.id].next_out;
deba@2338
   888
        }
deba@2338
   889
        if (e.id != -1) {
deba@2338
   890
          e.id /= 2;
deba@2338
   891
          return;
deba@2338
   892
        } 
deba@2338
   893
        n = nodes[n].next;
deba@2338
   894
      }
deba@2338
   895
      e.id = -1;
deba@2338
   896
    }
deba@2338
   897
deba@2338
   898
    void firstOut(Edge &e, const Node& v) const {
deba@2338
   899
      e.id = nodes[v.id].first_out;
deba@2338
   900
    }
deba@2338
   901
    void nextOut(Edge &e) const {
deba@2338
   902
      e.id = edges[e.id].next_out;
deba@2338
   903
    }
deba@2338
   904
deba@2338
   905
    void firstIn(Edge &e, const Node& v) const {
deba@2338
   906
      e.id = ((nodes[v.id].first_out) ^ 1);
deba@2338
   907
      if (e.id == -2) e.id = -1;
deba@2338
   908
    }
deba@2338
   909
    void nextIn(Edge &e) const {
deba@2338
   910
      e.id = ((edges[e.id ^ 1].next_out) ^ 1);
deba@2338
   911
      if (e.id == -2) e.id = -1;
deba@2338
   912
    }
deba@2338
   913
deba@2338
   914
    void firstInc(UEdge &e, bool& d, const Node& v) const {
deba@2338
   915
      int de = nodes[v.id].first_out;
deba@2381
   916
      if (de != -1 ) {
deba@2381
   917
        e.id = de / 2;
deba@2381
   918
        d = ((de & 1) == 1);
deba@2381
   919
      } else {
deba@2381
   920
        e.id = -1;
deba@2381
   921
        d = true;
deba@2381
   922
      }
deba@2338
   923
    }
deba@2338
   924
    void nextInc(UEdge &e, bool& d) const {
deba@2338
   925
      int de = (edges[(e.id * 2) | (d ? 1 : 0)].next_out);
deba@2381
   926
      if (de != -1 ) {
deba@2381
   927
        e.id = de / 2;
deba@2381
   928
        d = ((de & 1) == 1);
deba@2381
   929
      } else {
deba@2381
   930
        e.id = -1;
deba@2381
   931
        d = true;
deba@2381
   932
      }
deba@2338
   933
    }
deba@2338
   934
    
deba@2338
   935
    static int id(Node v) { return v.id; }
deba@2338
   936
    static int id(Edge e) { return e.id; }
deba@2338
   937
    static int id(UEdge e) { return e.id; }
deba@2338
   938
deba@2338
   939
    static Node nodeFromId(int id) { return Node(id);}
deba@2338
   940
    static Edge edgeFromId(int id) { return Edge(id);}
deba@2338
   941
    static UEdge uEdgeFromId(int id) { return UEdge(id);}
deba@2338
   942
deba@2338
   943
    Node addNode() {     
deba@2338
   944
      int n;
deba@2338
   945
      
deba@2338
   946
      if(first_free_node==-1) {
deba@2338
   947
	n = nodes.size();
deba@2338
   948
	nodes.push_back(NodeT());
deba@2338
   949
      } else {
deba@2338
   950
	n = first_free_node;
deba@2338
   951
	first_free_node = nodes[n].next;
deba@2338
   952
      }
deba@2338
   953
      
deba@2338
   954
      nodes[n].next = first_node;
deba@2338
   955
      if (first_node != -1) nodes[first_node].prev = n;
deba@2338
   956
      first_node = n;
deba@2338
   957
      nodes[n].prev = -1;
deba@2338
   958
      
deba@2338
   959
      nodes[n].first_out = -1;
deba@2338
   960
      
deba@2338
   961
      return Node(n);
deba@2338
   962
    }
deba@2338
   963
    
deba@2338
   964
    UEdge addEdge(Node u, Node v) {
deba@2338
   965
      int n;      
deba@2338
   966
deba@2338
   967
      if (first_free_edge == -1) {
deba@2338
   968
	n = edges.size();
deba@2338
   969
	edges.push_back(EdgeT());
deba@2338
   970
	edges.push_back(EdgeT());
deba@2338
   971
      } else {
deba@2338
   972
	n = first_free_edge;
deba@2338
   973
	first_free_edge = edges[n].next_out;
deba@2338
   974
      }
deba@2338
   975
      
deba@2338
   976
      edges[n].target = u.id;
deba@2338
   977
      edges[n | 1].target = v.id;
deba@2338
   978
deba@2338
   979
      edges[n].next_out = nodes[v.id].first_out;
deba@2338
   980
      if (nodes[v.id].first_out != -1) {
deba@2338
   981
	edges[nodes[v.id].first_out].prev_out = n;
deba@2498
   982
      }      
deba@2498
   983
      edges[n].prev_out = -1;
deba@2498
   984
      nodes[v.id].first_out = n;
deba@2498
   985
      
deba@2498
   986
      edges[n | 1].next_out = nodes[u.id].first_out;
deba@2338
   987
      if (nodes[u.id].first_out != -1) {
deba@2338
   988
	edges[nodes[u.id].first_out].prev_out = (n | 1);
deba@2338
   989
      }
deba@2498
   990
      edges[n | 1].prev_out = -1;      
deba@2338
   991
      nodes[u.id].first_out = (n | 1);
deba@2338
   992
deba@2338
   993
      return UEdge(n / 2);
deba@2338
   994
    }
deba@2338
   995
    
deba@2338
   996
    void erase(const Node& node) {
deba@2338
   997
      int n = node.id;
deba@2338
   998
      
deba@2338
   999
      if(nodes[n].next != -1) {
deba@2338
  1000
	nodes[nodes[n].next].prev = nodes[n].prev;
deba@2338
  1001
      }
deba@2338
  1002
      
deba@2338
  1003
      if(nodes[n].prev != -1) {
deba@2338
  1004
	nodes[nodes[n].prev].next = nodes[n].next;
deba@2338
  1005
      } else {
deba@2338
  1006
	first_node = nodes[n].next;
deba@2338
  1007
      }
deba@2338
  1008
      
deba@2338
  1009
      nodes[n].next = first_free_node;
deba@2338
  1010
      first_free_node = n;
deba@2338
  1011
deba@2338
  1012
    }
deba@2338
  1013
    
deba@2338
  1014
    void erase(const UEdge& edge) {
deba@2338
  1015
      int n = edge.id * 2;
deba@2338
  1016
      
deba@2338
  1017
      if (edges[n].next_out != -1) {
deba@2338
  1018
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
deba@2338
  1019
      } 
deba@2338
  1020
deba@2338
  1021
      if (edges[n].prev_out != -1) {
deba@2338
  1022
	edges[edges[n].prev_out].next_out = edges[n].next_out;
deba@2338
  1023
      } else {
deba@2338
  1024
	nodes[edges[n | 1].target].first_out = edges[n].next_out;
deba@2338
  1025
      }
deba@2338
  1026
deba@2338
  1027
      if (edges[n | 1].next_out != -1) {
deba@2338
  1028
	edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
deba@2338
  1029
      } 
deba@2338
  1030
deba@2338
  1031
      if (edges[n | 1].prev_out != -1) {
deba@2338
  1032
	edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
deba@2338
  1033
      } else {
deba@2338
  1034
	nodes[edges[n].target].first_out = edges[n | 1].next_out;
deba@2338
  1035
      }
deba@2338
  1036
      
deba@2338
  1037
      edges[n].next_out = first_free_edge;
deba@2338
  1038
      first_free_edge = n;      
deba@2338
  1039
deba@2338
  1040
    }
deba@2338
  1041
deba@2338
  1042
    void clear() {
deba@2338
  1043
      edges.clear();
deba@2338
  1044
      nodes.clear();
deba@2338
  1045
      first_node = first_free_node = first_free_edge = -1;
deba@2338
  1046
    }
deba@2338
  1047
deba@2338
  1048
  protected:
deba@2338
  1049
deba@2338
  1050
    void changeTarget(UEdge e, Node n) {
deba@2338
  1051
      if(edges[2 * e.id].next_out != -1) {
deba@2338
  1052
	edges[edges[2 * e.id].next_out].prev_out = edges[2 * e.id].prev_out;
deba@2338
  1053
      }
deba@2338
  1054
      if(edges[2 * e.id].prev_out != -1) {
deba@2338
  1055
	edges[edges[2 * e.id].prev_out].next_out = 
deba@2338
  1056
          edges[2 * e.id].next_out;
deba@2338
  1057
      } else {
deba@2338
  1058
        nodes[edges[(2 * e.id) | 1].target].first_out = 
deba@2338
  1059
          edges[2 * e.id].next_out;
deba@2338
  1060
      }
deba@2338
  1061
deba@2338
  1062
      if (nodes[n.id].first_out != -1) {
deba@2338
  1063
	edges[nodes[n.id].first_out].prev_out = 2 * e.id;
deba@2338
  1064
      }
deba@2338
  1065
      edges[(2 * e.id) | 1].target = n.id;
deba@2338
  1066
      edges[2 * e.id].prev_out = -1;
deba@2338
  1067
      edges[2 * e.id].next_out = nodes[n.id].first_out;
deba@2338
  1068
      nodes[n.id].first_out = 2 * e.id;
deba@2338
  1069
    }
deba@2338
  1070
deba@2338
  1071
    void changeSource(UEdge e, Node n) {
deba@2338
  1072
      if(edges[(2 * e.id) | 1].next_out != -1) {
deba@2338
  1073
	edges[edges[(2 * e.id) | 1].next_out].prev_out = 
deba@2338
  1074
          edges[(2 * e.id) | 1].prev_out;
deba@2338
  1075
      }
deba@2338
  1076
      if(edges[(2 * e.id) | 1].prev_out != -1) {
deba@2338
  1077
	edges[edges[(2 * e.id) | 1].prev_out].next_out = 
deba@2338
  1078
          edges[(2 * e.id) | 1].next_out;
deba@2338
  1079
      } else {
deba@2338
  1080
        nodes[edges[2 * e.id].target].first_out = 
deba@2338
  1081
          edges[(2 * e.id) | 1].next_out;
deba@2338
  1082
      }
deba@2338
  1083
deba@2338
  1084
      if (nodes[n.id].first_out != -1) {
deba@2338
  1085
	edges[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
deba@2338
  1086
      }
deba@2338
  1087
      edges[2 * e.id].target = n.id;
deba@2338
  1088
      edges[(2 * e.id) | 1].prev_out = -1;
deba@2338
  1089
      edges[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
deba@2338
  1090
      nodes[n.id].first_out = ((2 * e.id) | 1);
deba@2338
  1091
    }
deba@2338
  1092
deba@2338
  1093
  };
deba@2338
  1094
deba@2338
  1095
//   typedef UGraphExtender<UndirGraphExtender<ListGraphBase> > 
deba@2338
  1096
//   ExtendedListUGraphBase;
deba@2338
  1097
deba@2338
  1098
  typedef UGraphExtender<ListUGraphBase> ExtendedListUGraphBase;
deba@2338
  1099
deba@2338
  1100
deba@2116
  1101
deba@2116
  1102
  /// \addtogroup graphs
deba@2116
  1103
  /// @{
deba@2116
  1104
deba@2116
  1105
  ///An undirected list graph class.
deba@2116
  1106
alpar@2117
  1107
  ///This is a simple and fast undirected graph implementation.
deba@2116
  1108
  ///
alpar@2256
  1109
  ///An important extra feature of this graph implementation is that
alpar@2260
  1110
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
alpar@2256
  1111
  ///
deba@2116
  1112
  ///It conforms to the
alpar@2260
  1113
  ///\ref concepts::UGraph "UGraph concept".
deba@2116
  1114
  ///
alpar@2260
  1115
  ///\sa concepts::UGraph.
deba@2116
  1116
  ///
deba@2116
  1117
  class ListUGraph : public ExtendedListUGraphBase {
alpar@2128
  1118
  private:
alpar@2128
  1119
    ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
alpar@2128
  1120
alpar@2128
  1121
    ///ListUGraph is \e not copy constructible. Use UGraphCopy() instead.
alpar@2128
  1122
    ///
alpar@2128
  1123
    ListUGraph(const ListUGraph &) :ExtendedListUGraphBase()  {};
alpar@2132
  1124
    ///\brief Assignment of ListUGraph to another one is \e not allowed.
alpar@2128
  1125
    ///Use UGraphCopy() instead.
alpar@2128
  1126
alpar@2132
  1127
    ///Assignment of ListUGraph to another one is \e not allowed.
alpar@2128
  1128
    ///Use UGraphCopy() instead.
alpar@2128
  1129
    void operator=(const ListUGraph &) {}
deba@2116
  1130
  public:
alpar@2128
  1131
    /// Constructor
alpar@2128
  1132
    
alpar@2128
  1133
    /// Constructor.
alpar@2128
  1134
    ///
alpar@2128
  1135
    ListUGraph() {}
alpar@2128
  1136
deba@2116
  1137
    typedef ExtendedListUGraphBase Parent;
deba@2338
  1138
deba@2338
  1139
    typedef Parent::OutEdgeIt IncEdgeIt;
deba@2338
  1140
deba@2116
  1141
    /// \brief Add a new node to the graph.
deba@2116
  1142
    ///
deba@2116
  1143
    /// \return the new node.
deba@2116
  1144
    ///
deba@2116
  1145
    Node addNode() { return Parent::addNode(); }
deba@2116
  1146
deba@2116
  1147
    /// \brief Add a new edge to the graph.
deba@2116
  1148
    ///
deba@2116
  1149
    /// Add a new edge to the graph with source node \c s
deba@2116
  1150
    /// and target node \c t.
deba@2116
  1151
    /// \return the new undirected edge.
deba@2116
  1152
    UEdge addEdge(const Node& s, const Node& t) { 
deba@2116
  1153
      return Parent::addEdge(s, t); 
deba@2116
  1154
    }
deba@2160
  1155
    /// \brief Changes the source of \c e to \c n
deba@2160
  1156
    ///
deba@2160
  1157
    /// Changes the source of \c e to \c n
deba@2160
  1158
    ///
deba@2160
  1159
    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
deba@2160
  1160
    ///referencing the changed edge remain
deba@2160
  1161
    ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
deba@2160
  1162
    void changeSource(UEdge e, Node n) { 
deba@2160
  1163
      Parent::changeSource(e,n); 
deba@2160
  1164
    }    
deba@2116
  1165
    /// \brief Changes the target of \c e to \c n
deba@2116
  1166
    ///
deba@2116
  1167
    /// Changes the target of \c e to \c n
deba@2116
  1168
    ///
deba@2160
  1169
    /// \note The <tt>EdgeIt</tt>s referencing the changed edge remain
deba@2160
  1170
    /// valid. However the other iterators may be invalidated.
deba@2116
  1171
    void changeTarget(UEdge e, Node n) { 
deba@2116
  1172
      Parent::changeTarget(e,n); 
deba@2116
  1173
    }
deba@2160
  1174
    /// \brief Changes the source of \c e to \c n
deba@2116
  1175
    ///
deba@2160
  1176
    /// Changes the source of \c e to \c n. It changes the proper
deba@2160
  1177
    /// node of the represented undirected edge.
deba@2116
  1178
    ///
deba@2160
  1179
    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
deba@2116
  1180
    ///referencing the changed edge remain
deba@2160
  1181
    ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
deba@2160
  1182
    void changeSource(Edge e, Node n) { 
deba@2160
  1183
      if (Parent::direction(e)) {
deba@2160
  1184
        Parent::changeSource(e,n);
deba@2160
  1185
      } else {
deba@2160
  1186
        Parent::changeTarget(e,n);
deba@2160
  1187
      } 
deba@2160
  1188
    }
deba@2160
  1189
    /// \brief Changes the target of \c e to \c n
deba@2160
  1190
    ///
deba@2160
  1191
    /// Changes the target of \c e to \c n. It changes the proper
deba@2160
  1192
    /// node of the represented undirected edge.
deba@2160
  1193
    ///
deba@2160
  1194
    ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
deba@2160
  1195
    ///referencing the changed edge remain
deba@2160
  1196
    ///valid. However <tt>InEdgeIt</tt>s are invalidated.
deba@2160
  1197
    void changeTarget(Edge e, Node n) { 
deba@2160
  1198
      if (Parent::direction(e)) {
deba@2160
  1199
        Parent::changeTarget(e,n);
deba@2160
  1200
      } else {
deba@2160
  1201
        Parent::changeSource(e,n);
deba@2160
  1202
      } 
deba@2116
  1203
    }
deba@2116
  1204
    /// \brief Contract two nodes.
deba@2116
  1205
    ///
deba@2116
  1206
    /// This function contracts two nodes.
deba@2116
  1207
    ///
deba@2116
  1208
    /// Node \p b will be removed but instead of deleting
deba@2116
  1209
    /// its neighboring edges, they will be joined to \p a.
deba@2116
  1210
    /// The last parameter \p r controls whether to remove loops. \c true
deba@2116
  1211
    /// means that loops will be removed.
deba@2116
  1212
    ///
deba@2160
  1213
    /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
deba@2116
  1214
    /// valid.
deba@2116
  1215
    void contract(Node a, Node b, bool r = true) {
deba@2116
  1216
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
deba@2116
  1217
	IncEdgeIt f = e; ++f;
deba@2116
  1218
	if (r && runningNode(e) == a) {
deba@2116
  1219
	  erase(e);
deba@2116
  1220
	} else if (source(e) == b) {
deba@2116
  1221
	  changeSource(e, a);
deba@2116
  1222
	} else {
deba@2116
  1223
	  changeTarget(e, a);
deba@2116
  1224
	}
deba@2116
  1225
	e = f;
deba@2116
  1226
      }
deba@2116
  1227
      erase(b);
deba@2116
  1228
    }
deba@2189
  1229
deba@2189
  1230
deba@2189
  1231
    /// \brief Class to make a snapshot of the graph and restore
deba@2189
  1232
    /// to it later.
deba@2189
  1233
    ///
deba@2189
  1234
    /// Class to make a snapshot of the graph and to restore it
deba@2189
  1235
    /// later.
deba@2189
  1236
    ///
deba@2189
  1237
    /// The newly added nodes and undirected edges can be removed
deba@2189
  1238
    /// using the restore() function.
deba@2189
  1239
    ///
deba@2189
  1240
    /// \warning Edge and node deletions cannot be restored. This
deba@2189
  1241
    /// events invalidate the snapshot. 
deba@2189
  1242
    class Snapshot {
deba@2189
  1243
    protected:
deba@2189
  1244
deba@2189
  1245
      typedef Parent::NodeNotifier NodeNotifier;
deba@2189
  1246
deba@2189
  1247
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
deba@2189
  1248
      public:
deba@2189
  1249
deba@2189
  1250
        NodeObserverProxy(Snapshot& _snapshot)
deba@2189
  1251
          : snapshot(_snapshot) {}
deba@2189
  1252
deba@2189
  1253
        using NodeNotifier::ObserverBase::attach;
deba@2189
  1254
        using NodeNotifier::ObserverBase::detach;
deba@2189
  1255
        using NodeNotifier::ObserverBase::attached;
deba@2189
  1256
        
deba@2189
  1257
      protected:
deba@2189
  1258
        
deba@2189
  1259
        virtual void add(const Node& node) {
deba@2189
  1260
          snapshot.addNode(node);
deba@2189
  1261
        }
deba@2189
  1262
        virtual void add(const std::vector<Node>& nodes) {
deba@2189
  1263
          for (int i = nodes.size() - 1; i >= 0; ++i) {
deba@2189
  1264
            snapshot.addNode(nodes[i]);
deba@2189
  1265
          }
deba@2189
  1266
        }
deba@2189
  1267
        virtual void erase(const Node& node) {
deba@2189
  1268
          snapshot.eraseNode(node);
deba@2189
  1269
        }
deba@2189
  1270
        virtual void erase(const std::vector<Node>& nodes) {
deba@2386
  1271
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@2189
  1272
            snapshot.eraseNode(nodes[i]);
deba@2189
  1273
          }
deba@2189
  1274
        }
deba@2189
  1275
        virtual void build() {
deba@2189
  1276
          Node node;
deba@2189
  1277
          std::vector<Node> nodes;
deba@2386
  1278
          for (notifier()->first(node); node != INVALID; 
deba@2386
  1279
               notifier()->next(node)) {
deba@2189
  1280
            nodes.push_back(node);
deba@2189
  1281
          }
deba@2189
  1282
          for (int i = nodes.size() - 1; i >= 0; --i) {
deba@2189
  1283
            snapshot.addNode(nodes[i]);
deba@2189
  1284
          }
deba@2189
  1285
        }
deba@2189
  1286
        virtual void clear() {
deba@2189
  1287
          Node node;
deba@2386
  1288
          for (notifier()->first(node); node != INVALID; 
deba@2386
  1289
               notifier()->next(node)) {
deba@2189
  1290
            snapshot.eraseNode(node);
deba@2189
  1291
          }
deba@2189
  1292
        }
deba@2189
  1293
deba@2189
  1294
        Snapshot& snapshot;
deba@2189
  1295
      };
deba@2189
  1296
deba@2189
  1297
      class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
deba@2189
  1298
      public:
deba@2189
  1299
deba@2189
  1300
        UEdgeObserverProxy(Snapshot& _snapshot)
deba@2189
  1301
          : snapshot(_snapshot) {}
deba@2189
  1302
deba@2189
  1303
        using UEdgeNotifier::ObserverBase::attach;
deba@2189
  1304
        using UEdgeNotifier::ObserverBase::detach;
deba@2189
  1305
        using UEdgeNotifier::ObserverBase::attached;
deba@2189
  1306
        
deba@2189
  1307
      protected:
deba@2189
  1308
deba@2189
  1309
        virtual void add(const UEdge& edge) {
deba@2189
  1310
          snapshot.addUEdge(edge);
deba@2189
  1311
        }
deba@2189
  1312
        virtual void add(const std::vector<UEdge>& edges) {
deba@2189
  1313
          for (int i = edges.size() - 1; i >= 0; ++i) {
deba@2189
  1314
            snapshot.addUEdge(edges[i]);
deba@2189
  1315
          }
deba@2189
  1316
        }
deba@2189
  1317
        virtual void erase(const UEdge& edge) {
deba@2189
  1318
          snapshot.eraseUEdge(edge);
deba@2189
  1319
        }
deba@2189
  1320
        virtual void erase(const std::vector<UEdge>& edges) {
deba@2386
  1321
          for (int i = 0; i < int(edges.size()); ++i) {
deba@2189
  1322
            snapshot.eraseUEdge(edges[i]);
deba@2189
  1323
          }
deba@2189
  1324
        }
deba@2189
  1325
        virtual void build() {
deba@2189
  1326
          UEdge edge;
deba@2189
  1327
          std::vector<UEdge> edges;
deba@2386
  1328
          for (notifier()->first(edge); edge != INVALID; 
deba@2386
  1329
               notifier()->next(edge)) {
deba@2189
  1330
            edges.push_back(edge);
deba@2189
  1331
          }
deba@2189
  1332
          for (int i = edges.size() - 1; i >= 0; --i) {
deba@2189
  1333
            snapshot.addUEdge(edges[i]);
deba@2189
  1334
          }
deba@2189
  1335
        }
deba@2189
  1336
        virtual void clear() {
deba@2189
  1337
          UEdge edge;
deba@2386
  1338
          for (notifier()->first(edge); edge != INVALID; 
deba@2386
  1339
               notifier()->next(edge)) {
deba@2189
  1340
            snapshot.eraseUEdge(edge);
deba@2189
  1341
          }
deba@2189
  1342
        }
deba@2189
  1343
deba@2189
  1344
        Snapshot& snapshot;
deba@2189
  1345
      };
deba@2189
  1346
      
deba@2189
  1347
      ListUGraph *graph;
deba@2189
  1348
deba@2189
  1349
      NodeObserverProxy node_observer_proxy;
deba@2189
  1350
      UEdgeObserverProxy edge_observer_proxy;
deba@2189
  1351
deba@2189
  1352
      std::list<Node> added_nodes;
deba@2189
  1353
      std::list<UEdge> added_edges;
deba@2189
  1354
deba@2189
  1355
deba@2189
  1356
      void addNode(const Node& node) {
deba@2189
  1357
        added_nodes.push_front(node);        
deba@2189
  1358
      }
deba@2189
  1359
      void eraseNode(const Node& node) {
deba@2189
  1360
        std::list<Node>::iterator it = 
deba@2189
  1361
          std::find(added_nodes.begin(), added_nodes.end(), node);
deba@2189
  1362
        if (it == added_nodes.end()) {
deba@2189
  1363
          clear();
deba@2189
  1364
          edge_observer_proxy.detach();
deba@2189
  1365
          throw NodeNotifier::ImmediateDetach();
deba@2189
  1366
        } else {
deba@2189
  1367
          added_nodes.erase(it);
deba@2189
  1368
        }
deba@2189
  1369
      }
deba@2189
  1370
deba@2189
  1371
      void addUEdge(const UEdge& edge) {
deba@2189
  1372
        added_edges.push_front(edge);        
deba@2189
  1373
      }
deba@2189
  1374
      void eraseUEdge(const UEdge& edge) {
deba@2189
  1375
        std::list<UEdge>::iterator it = 
deba@2189
  1376
          std::find(added_edges.begin(), added_edges.end(), edge);
deba@2189
  1377
        if (it == added_edges.end()) {
deba@2189
  1378
          clear();
deba@2189
  1379
          node_observer_proxy.detach();
deba@2189
  1380
          throw UEdgeNotifier::ImmediateDetach();
deba@2189
  1381
        } else {
deba@2189
  1382
          added_edges.erase(it);
deba@2189
  1383
        }        
deba@2189
  1384
      }
deba@2189
  1385
deba@2189
  1386
      void attach(ListUGraph &_graph) {
deba@2189
  1387
	graph = &_graph;
deba@2381
  1388
	node_observer_proxy.attach(graph->notifier(Node()));
deba@2381
  1389
        edge_observer_proxy.attach(graph->notifier(UEdge()));
deba@2189
  1390
      }
deba@2189
  1391
            
deba@2189
  1392
      void detach() {
deba@2189
  1393
	node_observer_proxy.detach();
deba@2189
  1394
	edge_observer_proxy.detach();
deba@2189
  1395
      }
deba@2189
  1396
deba@2189
  1397
      bool attached() const {
deba@2189
  1398
        return node_observer_proxy.attached();
deba@2189
  1399
      }
deba@2189
  1400
deba@2189
  1401
      void clear() {
deba@2189
  1402
        added_nodes.clear();
deba@2189
  1403
        added_edges.clear();        
deba@2189
  1404
      }
deba@2189
  1405
deba@2189
  1406
    public:
deba@2189
  1407
deba@2189
  1408
      /// \brief Default constructor.
deba@2189
  1409
      ///
deba@2189
  1410
      /// Default constructor.
deba@2189
  1411
      /// To actually make a snapshot you must call save().
deba@2189
  1412
      Snapshot() 
deba@2189
  1413
        : graph(0), node_observer_proxy(*this), 
deba@2189
  1414
          edge_observer_proxy(*this) {}
deba@2189
  1415
      
deba@2189
  1416
      /// \brief Constructor that immediately makes a snapshot.
deba@2189
  1417
      ///      
deba@2189
  1418
      /// This constructor immediately makes a snapshot of the graph.
deba@2189
  1419
      /// \param _graph The graph we make a snapshot of.
deba@2189
  1420
      Snapshot(ListUGraph &_graph) 
deba@2189
  1421
        : node_observer_proxy(*this), 
deba@2189
  1422
          edge_observer_proxy(*this) {
deba@2189
  1423
	attach(_graph);
deba@2189
  1424
      }
deba@2189
  1425
      
deba@2189
  1426
      /// \brief Make a snapshot.
deba@2189
  1427
      ///
deba@2189
  1428
      /// Make a snapshot of the graph.
deba@2189
  1429
      ///
deba@2189
  1430
      /// This function can be called more than once. In case of a repeated
deba@2189
  1431
      /// call, the previous snapshot gets lost.
deba@2189
  1432
      /// \param _graph The graph we make the snapshot of.
deba@2189
  1433
      void save(ListUGraph &_graph) {
deba@2189
  1434
        if (attached()) {
deba@2189
  1435
          detach();
deba@2189
  1436
          clear();
deba@2189
  1437
        }
deba@2189
  1438
        attach(_graph);
deba@2189
  1439
      }
deba@2189
  1440
      
deba@2189
  1441
      /// \brief Undo the changes until the last snapshot.
deba@2189
  1442
      // 
deba@2189
  1443
      /// Undo the changes until the last snapshot created by save().
deba@2189
  1444
      void restore() {
deba@2189
  1445
	detach();
deba@2189
  1446
	for(std::list<UEdge>::iterator it = added_edges.begin(); 
deba@2189
  1447
            it != added_edges.end(); ++it) {
deba@2189
  1448
	  graph->erase(*it);
deba@2189
  1449
	}
deba@2189
  1450
	for(std::list<Node>::iterator it = added_nodes.begin(); 
deba@2189
  1451
            it != added_nodes.end(); ++it) {
deba@2189
  1452
	  graph->erase(*it);
deba@2189
  1453
	}
deba@2189
  1454
        clear();
deba@2189
  1455
      }
deba@2189
  1456
deba@2189
  1457
      /// \brief Gives back true when the snapshot is valid.
deba@2189
  1458
      ///
deba@2189
  1459
      /// Gives back true when the snapshot is valid.
deba@2189
  1460
      bool valid() const {
deba@2189
  1461
        return attached();
deba@2189
  1462
      }
deba@2189
  1463
    };
deba@2116
  1464
  };
deba@2116
  1465
deba@2116
  1466
deba@2116
  1467
  class ListBpUGraphBase {
deba@2116
  1468
  public:
deba@2116
  1469
deba@2116
  1470
    class NodeSetError : public LogicError {
deba@2160
  1471
    public:
alpar@2151
  1472
      virtual const char* what() const throw() { 
deba@2116
  1473
	return "lemon::ListBpUGraph::NodeSetError";
deba@2116
  1474
      }
deba@2116
  1475
    };
deba@2116
  1476
deba@2116
  1477
  protected:
deba@2116
  1478
deba@2116
  1479
    struct NodeT {
deba@2116
  1480
      int first_edge, prev, next;
deba@2116
  1481
    };
deba@2116
  1482
deba@2116
  1483
    struct UEdgeT {
deba@2116
  1484
      int aNode, prev_out, next_out;
deba@2116
  1485
      int bNode, prev_in, next_in;
deba@2116
  1486
    };
deba@2116
  1487
deba@2116
  1488
    std::vector<NodeT> aNodes;
deba@2116
  1489
    std::vector<NodeT> bNodes;
deba@2116
  1490
deba@2116
  1491
    std::vector<UEdgeT> edges;
deba@2116
  1492
deba@2116
  1493
    int first_anode;
deba@2116
  1494
    int first_free_anode;
deba@2116
  1495
deba@2116
  1496
    int first_bnode;
deba@2116
  1497
    int first_free_bnode;
deba@2116
  1498
deba@2116
  1499
    int first_free_edge;
deba@2116
  1500
deba@2116
  1501
  public:
deba@2116
  1502
  
deba@2116
  1503
    class Node {
deba@2116
  1504
      friend class ListBpUGraphBase;
deba@2116
  1505
    protected:
deba@2116
  1506
      int id;
deba@2116
  1507
deba@2116
  1508
      explicit Node(int _id) : id(_id) {}
deba@2116
  1509
    public:
deba@2116
  1510
      Node() {}
deba@2116
  1511
      Node(Invalid) { id = -1; }
deba@2116
  1512
      bool operator==(const Node i) const {return id==i.id;}
deba@2116
  1513
      bool operator!=(const Node i) const {return id!=i.id;}
deba@2116
  1514
      bool operator<(const Node i) const {return id<i.id;}
deba@2116
  1515
    };
deba@2116
  1516
deba@2116
  1517
    class UEdge {
deba@2116
  1518
      friend class ListBpUGraphBase;
deba@2116
  1519
    protected:
deba@2116
  1520
      int id;
deba@2116
  1521
deba@2116
  1522
      explicit UEdge(int _id) { id = _id;}
deba@2116
  1523
    public:
deba@2116
  1524
      UEdge() {}
deba@2116
  1525
      UEdge (Invalid) { id = -1; }
deba@2116
  1526
      bool operator==(const UEdge i) const {return id==i.id;}
deba@2116
  1527
      bool operator!=(const UEdge i) const {return id!=i.id;}
deba@2116
  1528
      bool operator<(const UEdge i) const {return id<i.id;}
deba@2116
  1529
    };
deba@2116
  1530
deba@2116
  1531
    ListBpUGraphBase()
deba@2116
  1532
      : first_anode(-1), first_free_anode(-1),
deba@2116
  1533
        first_bnode(-1), first_free_bnode(-1),
deba@2116
  1534
        first_free_edge(-1) {}
deba@2116
  1535
deba@2116
  1536
    void firstANode(Node& node) const {
deba@2116
  1537
      node.id = first_anode != -1 ? (first_anode << 1) : -1;
deba@2116
  1538
    }
deba@2116
  1539
    void nextANode(Node& node) const {
deba@2116
  1540
      node.id = aNodes[node.id >> 1].next;
deba@2116
  1541
    }
deba@2116
  1542
deba@2116
  1543
    void firstBNode(Node& node) const {
deba@2116
  1544
      node.id = first_bnode != -1 ? (first_bnode << 1) + 1 : -1;
deba@2116
  1545
    }
deba@2116
  1546
    void nextBNode(Node& node) const {
deba@2116
  1547
      node.id = bNodes[node.id >> 1].next;
deba@2116
  1548
    }
deba@2116
  1549
deba@2116
  1550
    void first(Node& node) const {
deba@2116
  1551
      if (first_anode != -1) {
deba@2116
  1552
        node.id = (first_anode << 1);
deba@2116
  1553
      } else if (first_bnode != -1) {
deba@2116
  1554
        node.id = (first_bnode << 1) + 1;
deba@2116
  1555
      } else {
deba@2116
  1556
        node.id = -1;
deba@2116
  1557
      }
deba@2116
  1558
    }
deba@2116
  1559
    void next(Node& node) const {
deba@2116
  1560
      if (aNode(node)) {
deba@2116
  1561
        node.id = aNodes[node.id >> 1].next;
deba@2116
  1562
        if (node.id == -1) {
deba@2116
  1563
          if (first_bnode != -1) {
deba@2116
  1564
            node.id = (first_bnode << 1) + 1;
deba@2116
  1565
          }
deba@2116
  1566
        }
deba@2116
  1567
      } else {
deba@2116
  1568
        node.id = bNodes[node.id >> 1].next;
deba@2116
  1569
      }
deba@2116
  1570
    }
deba@2116
  1571
  
deba@2116
  1572
    void first(UEdge& edge) const {
deba@2386
  1573
      int aid = first_anode;
deba@2386
  1574
      while (aid != -1 && aNodes[aid].first_edge == -1) {
deba@2386
  1575
        aid = aNodes[aid].next != -1 ? 
deba@2386
  1576
          aNodes[aid].next >> 1 : -1;
deba@2116
  1577
      }
deba@2386
  1578
      if (aid != -1) {
deba@2386
  1579
        edge.id = aNodes[aid].first_edge;
deba@2116
  1580
      } else {
deba@2116
  1581
        edge.id = -1;
deba@2116
  1582
      }
deba@2116
  1583
    }
deba@2116
  1584
    void next(UEdge& edge) const {
deba@2386
  1585
      int aid = edges[edge.id].aNode >> 1;
deba@2116
  1586
      edge.id = edges[edge.id].next_out;
deba@2116
  1587
      if (edge.id == -1) {
deba@2386
  1588
        aid = aNodes[aid].next != -1 ? 
deba@2386
  1589
          aNodes[aid].next >> 1 : -1;
deba@2386
  1590
        while (aid != -1 && aNodes[aid].first_edge == -1) {
deba@2386
  1591
          aid = aNodes[aid].next != -1 ? 
deba@2386
  1592
          aNodes[aid].next >> 1 : -1;
deba@2116
  1593
        }
deba@2386
  1594
        if (aid != -1) {
deba@2386
  1595
          edge.id = aNodes[aid].first_edge;
deba@2116
  1596
        } else {
deba@2116
  1597
          edge.id = -1;
deba@2116
  1598
        }
deba@2116
  1599
      }
deba@2116
  1600
    }
deba@2116
  1601
deba@2116
  1602
    void firstFromANode(UEdge& edge, const Node& node) const {
deba@2116
  1603
      LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
deba@2116
  1604
      edge.id = aNodes[node.id >> 1].first_edge;
deba@2116
  1605
    }
deba@2116
  1606
    void nextFromANode(UEdge& edge) const {
deba@2116
  1607
      edge.id = edges[edge.id].next_out;
deba@2116
  1608
    }
deba@2116
  1609
deba@2116
  1610
    void firstFromBNode(UEdge& edge, const Node& node) const {
deba@2116
  1611
      LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
deba@2116
  1612
      edge.id = bNodes[node.id >> 1].first_edge;
deba@2116
  1613
    }
deba@2116
  1614
    void nextFromBNode(UEdge& edge) const {
deba@2116
  1615
      edge.id = edges[edge.id].next_in;
deba@2116
  1616
    }
deba@2116
  1617
deba@2116
  1618
    static int id(const Node& node) {
deba@2116
  1619
      return node.id;
deba@2116
  1620
    }
deba@2116
  1621
    static Node nodeFromId(int id) {
deba@2116
  1622
      return Node(id);
deba@2116
  1623
    }
deba@2116
  1624
    int maxNodeId() const {
deba@2116
  1625
      return aNodes.size() > bNodes.size() ?
deba@2116
  1626
	aNodes.size() * 2 - 2 : bNodes.size() * 2 - 1;
deba@2116
  1627
    }
deba@2116
  1628
  
deba@2116
  1629
    static int id(const UEdge& edge) {
deba@2116
  1630
      return edge.id;
deba@2116
  1631
    }
deba@2116
  1632
    static UEdge uEdgeFromId(int id) {
deba@2116
  1633
      return UEdge(id);
deba@2116
  1634
    }
deba@2116
  1635
    int maxUEdgeId() const {
deba@2116
  1636
      return edges.size();
deba@2116
  1637
    }
deba@2116
  1638
  
deba@2116
  1639
    static int aNodeId(const Node& node) {
deba@2116
  1640
      return node.id >> 1;
deba@2116
  1641
    }
deba@2231
  1642
    static Node nodeFromANodeId(int id) {
deba@2116
  1643
      return Node(id << 1);
deba@2116
  1644
    }
deba@2116
  1645
    int maxANodeId() const {
deba@2116
  1646
      return aNodes.size();
deba@2116
  1647
    }
deba@2116
  1648
deba@2116
  1649
    static int bNodeId(const Node& node) {
deba@2116
  1650
      return node.id >> 1;
deba@2116
  1651
    }
deba@2231
  1652
    static Node nodeFromBNodeId(int id) {
deba@2116
  1653
      return Node((id << 1) + 1);
deba@2116
  1654
    }
deba@2116
  1655
    int maxBNodeId() const {
deba@2116
  1656
      return bNodes.size();
deba@2116
  1657
    }
deba@2116
  1658
deba@2116
  1659
    Node aNode(const UEdge& edge) const {
deba@2116
  1660
      return Node(edges[edge.id].aNode);
deba@2116
  1661
    }
deba@2116
  1662
    Node bNode(const UEdge& edge) const {
deba@2116
  1663
      return Node(edges[edge.id].bNode);
deba@2116
  1664
    }
deba@2116
  1665
deba@2116
  1666
    static bool aNode(const Node& node) {
deba@2116
  1667
      return (node.id & 1) == 0;
deba@2116
  1668
    }
deba@2116
  1669
deba@2116
  1670
    static bool bNode(const Node& node) {
deba@2116
  1671
      return (node.id & 1) == 1;
deba@2116
  1672
    }
deba@2116
  1673
deba@2116
  1674
    Node addANode() {
deba@2386
  1675
      int aid;
deba@2116
  1676
      if (first_free_anode == -1) {
deba@2386
  1677
        aid = aNodes.size();
deba@2116
  1678
        aNodes.push_back(NodeT());
deba@2116
  1679
      } else {
deba@2386
  1680
        aid = first_free_anode;
deba@2116
  1681
        first_free_anode = aNodes[first_free_anode].next;
deba@2116
  1682
      }
deba@2116
  1683
      if (first_anode != -1) {
deba@2386
  1684
        aNodes[aid].next = first_anode << 1;
deba@2386
  1685
        aNodes[first_anode].prev = aid << 1;
deba@2116
  1686
      } else {
deba@2386
  1687
        aNodes[aid].next = -1;
deba@2116
  1688
      }
deba@2386
  1689
      aNodes[aid].prev = -1;
deba@2386
  1690
      first_anode = aid;
deba@2386
  1691
      aNodes[aid].first_edge = -1;
deba@2386
  1692
      return Node(aid << 1);
deba@2116
  1693
    }
deba@2116
  1694
deba@2116
  1695
    Node addBNode() {
deba@2386
  1696
      int bid;
deba@2116
  1697
      if (first_free_bnode == -1) {
deba@2386
  1698
        bid = bNodes.size();
deba@2116
  1699
        bNodes.push_back(NodeT());
deba@2116
  1700
      } else {
deba@2386
  1701
        bid = first_free_bnode;
deba@2116
  1702
        first_free_bnode = bNodes[first_free_bnode].next;
deba@2116
  1703
      }
deba@2116
  1704
      if (first_bnode != -1) {
deba@2386
  1705
        bNodes[bid].next = (first_bnode << 1) + 1;
deba@2386
  1706
        bNodes[first_bnode].prev = (bid << 1) + 1;
deba@2116
  1707
      } else {
deba@2386
  1708
        bNodes[bid].next = -1;
deba@2116
  1709
      }
deba@2386
  1710
      bNodes[bid].prev = -1;
deba@2386
  1711
      first_bnode = bid;
deba@2386
  1712
      bNodes[bid].first_edge = -1;
deba@2386
  1713
      return Node((bid << 1) + 1);
deba@2116
  1714
    }
deba@2116
  1715
deba@2116
  1716
    UEdge addEdge(const Node& source, const Node& target) {
deba@2116
  1717
      LEMON_ASSERT(((source.id ^ target.id) & 1) == 1, NodeSetError());
deba@2116
  1718
      int edgeId;
deba@2116
  1719
      if (first_free_edge != -1) {
deba@2116
  1720
        edgeId = first_free_edge;
deba@2116
  1721
        first_free_edge = edges[edgeId].next_out;
deba@2116
  1722
      } else {
deba@2116
  1723
        edgeId = edges.size();
deba@2116
  1724
        edges.push_back(UEdgeT());
deba@2116
  1725
      }
deba@2116
  1726
      if ((source.id & 1) == 0) {
deba@2116
  1727
	edges[edgeId].aNode = source.id;
deba@2116
  1728
	edges[edgeId].bNode = target.id;
deba@2116
  1729
      } else {
deba@2116
  1730
	edges[edgeId].aNode = target.id;
deba@2116
  1731
	edges[edgeId].bNode = source.id;
deba@2116
  1732
      }
deba@2116
  1733
      edges[edgeId].next_out = aNodes[edges[edgeId].aNode >> 1].first_edge;
deba@2116
  1734
      edges[edgeId].prev_out = -1;
deba@2116
  1735
      if (aNodes[edges[edgeId].aNode >> 1].first_edge != -1) {
deba@2116
  1736
        edges[aNodes[edges[edgeId].aNode >> 1].first_edge].prev_out = edgeId;
deba@2116
  1737
      }
deba@2116
  1738
      aNodes[edges[edgeId].aNode >> 1].first_edge = edgeId;
deba@2116
  1739
      edges[edgeId].next_in = bNodes[edges[edgeId].bNode >> 1].first_edge;
deba@2116
  1740
      edges[edgeId].prev_in = -1;
deba@2116
  1741
      if (bNodes[edges[edgeId].bNode >> 1].first_edge != -1) {
deba@2116
  1742
        edges[bNodes[edges[edgeId].bNode >> 1].first_edge].prev_in = edgeId;
deba@2116
  1743
      }
deba@2116
  1744
      bNodes[edges[edgeId].bNode >> 1].first_edge = edgeId;
deba@2116
  1745
      return UEdge(edgeId);
deba@2116
  1746
    }
deba@2116
  1747
deba@2116
  1748
    void erase(const Node& node) {
deba@2116
  1749
      if (aNode(node)) {
deba@2386
  1750
        int aid = node.id >> 1;
deba@2386
  1751
        if (aNodes[aid].prev != -1) {
deba@2386
  1752
          aNodes[aNodes[aid].prev >> 1].next = aNodes[aid].next;
deba@2116
  1753
        } else {
deba@2189
  1754
          first_anode = 
deba@2386
  1755
            aNodes[aid].next != -1 ? aNodes[aid].next >> 1 : -1;
deba@2116
  1756
        }
deba@2386
  1757
        if (aNodes[aid].next != -1) {
deba@2386
  1758
          aNodes[aNodes[aid].next >> 1].prev = aNodes[aid].prev;
deba@2116
  1759
        }
deba@2386
  1760
        aNodes[aid].next = first_free_anode;
deba@2386
  1761
        first_free_anode = aid;
deba@2116
  1762
      } else {
deba@2386
  1763
        int bid = node.id >> 1;
deba@2386
  1764
        if (bNodes[bid].prev != -1) {
deba@2386
  1765
          bNodes[bNodes[bid].prev >> 1].next = bNodes[bid].next;
deba@2116
  1766
        } else {
deba@2189
  1767
          first_bnode = 
deba@2386
  1768
            bNodes[bid].next != -1 ? bNodes[bid].next >> 1 : -1;
deba@2116
  1769
        }
deba@2386
  1770
        if (bNodes[bid].next != -1) {
deba@2386
  1771
          bNodes[bNodes[bid].next >> 1].prev = bNodes[bid].prev;
deba@2116
  1772
        }
deba@2386
  1773
        bNodes[bid].next = first_free_bnode;
deba@2386
  1774
        first_free_bnode = bid;
deba@2116
  1775
      }
deba@2116
  1776
    }
deba@2116
  1777
deba@2116
  1778
    void erase(const UEdge& edge) {
deba@2116
  1779
deba@2116
  1780
      if (edges[edge.id].prev_out != -1) {
deba@2116
  1781
        edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
deba@2116
  1782
      } else {
deba@2116
  1783
        aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
deba@2116
  1784
      }
deba@2116
  1785
      if (edges[edge.id].next_out != -1) {
deba@2116
  1786
        edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;
deba@2116
  1787
      }
deba@2116
  1788
deba@2116
  1789
      if (edges[edge.id].prev_in != -1) {
deba@2116
  1790
        edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
deba@2116
  1791
      } else {
deba@2116
  1792
        bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
deba@2116
  1793
      }
deba@2116
  1794
      if (edges[edge.id].next_in != -1) {
deba@2116
  1795
        edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;
deba@2116
  1796
      }
deba@2116
  1797
deba@2116
  1798
      edges[edge.id].next_out = first_free_edge;
deba@2116
  1799
      first_free_edge = edge.id;
deba@2116
  1800
    }
alpar@2128
  1801
 
deba@2116
  1802
    void clear() {
deba@2116
  1803
      aNodes.clear();
deba@2116
  1804
      bNodes.clear();
deba@2116
  1805
      edges.clear();
deba@2116
  1806
      first_anode = -1;
deba@2116
  1807
      first_free_anode = -1;
deba@2116
  1808
      first_bnode = -1;
deba@2116
  1809
      first_free_bnode = -1;
deba@2116
  1810
      first_free_edge = -1;
deba@2116
  1811
    }
deba@2116
  1812
deba@2160
  1813
    void changeANode(const UEdge& edge, const Node& node) {
deba@2160
  1814
      LEMON_ASSERT((node.id & 1) == 0, NodeSetError());
deba@2160
  1815
      if (edges[edge.id].prev_out != -1) {
deba@2160
  1816
        edges[edges[edge.id].prev_out].next_out = edges[edge.id].next_out;
deba@2160
  1817
      } else {
deba@2160
  1818
        aNodes[edges[edge.id].aNode >> 1].first_edge = edges[edge.id].next_out;
deba@2160
  1819
      }
deba@2160
  1820
      if (edges[edge.id].next_out != -1) {
deba@2160
  1821
        edges[edges[edge.id].next_out].prev_out = edges[edge.id].prev_out;  
deba@2160
  1822
      }
deba@2160
  1823
      if (aNodes[node.id >> 1].first_edge != -1) {
deba@2160
  1824
        edges[aNodes[node.id >> 1].first_edge].prev_out = edge.id;
deba@2160
  1825
      }
deba@2160
  1826
      edges[edge.id].prev_out = -1;
deba@2160
  1827
      edges[edge.id].next_out = aNodes[node.id >> 1].first_edge;
deba@2160
  1828
      aNodes[node.id >> 1].first_edge = edge.id;
deba@2160
  1829
      edges[edge.id].aNode = node.id;
deba@2160
  1830
    } 
deba@2160
  1831
deba@2160
  1832
    void changeBNode(const UEdge& edge, const Node& node) {
deba@2160
  1833
      LEMON_ASSERT((node.id & 1) == 1, NodeSetError());
deba@2160
  1834
      if (edges[edge.id].prev_in != -1) {
deba@2160
  1835
        edges[edges[edge.id].prev_in].next_in = edges[edge.id].next_in;
deba@2160
  1836
      } else {
deba@2160
  1837
        bNodes[edges[edge.id].bNode >> 1].first_edge = edges[edge.id].next_in;
deba@2160
  1838
      }
deba@2160
  1839
      if (edges[edge.id].next_in != -1) {
deba@2160
  1840
        edges[edges[edge.id].next_in].prev_in = edges[edge.id].prev_in;  
deba@2160
  1841
      }
deba@2160
  1842
      if (bNodes[node.id >> 1].first_edge != -1) {
deba@2160
  1843
        edges[bNodes[node.id >> 1].first_edge].prev_in = edge.id;
deba@2160
  1844
      }
deba@2160
  1845
      edges[edge.id].prev_in = -1;
deba@2160
  1846
      edges[edge.id].next_in = bNodes[node.id >> 1].first_edge;
deba@2160
  1847
      bNodes[node.id >> 1].first_edge = edge.id;
deba@2160
  1848
      edges[edge.id].bNode = node.id;
deba@2160
  1849
    } 
deba@2160
  1850
deba@2116
  1851
  };
deba@2116
  1852
deba@2116
  1853
deba@2231
  1854
  typedef BpUGraphExtender<BidirBpUGraphExtender<ListBpUGraphBase> > 
deba@2231
  1855
  ExtendedListBpUGraphBase;
deba@2116
  1856
deba@2116
  1857
  /// \ingroup graphs
deba@2116
  1858
  ///
deba@2116
  1859
  /// \brief A smart bipartite undirected graph class.
deba@2116
  1860
  ///
deba@2116
  1861
  /// This is a bipartite undirected graph implementation.
alpar@2260
  1862
  /// It is conforms to the \ref concepts::BpUGraph "BpUGraph concept".
alpar@2256
  1863
  ///
alpar@2256
  1864
  ///An important extra feature of this graph implementation is that
alpar@2260
  1865
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
alpar@2256
  1866
  ///
alpar@2260
  1867
  /// \sa concepts::BpUGraph.
deba@2116
  1868
  ///
deba@2160
  1869
  class ListBpUGraph : public ExtendedListBpUGraphBase {
deba@2160
  1870
    /// \brief ListBpUGraph is \e not copy constructible.
deba@2160
  1871
    ///
deba@2160
  1872
    ///ListBpUGraph is \e not copy constructible.
deba@2160
  1873
    ListBpUGraph(const ListBpUGraph &) :ExtendedListBpUGraphBase()  {};
deba@2160
  1874
    /// \brief Assignment of ListBpUGraph to another one is \e not
deba@2160
  1875
    /// allowed.
deba@2160
  1876
    ///
deba@2160
  1877
    /// Assignment of ListBpUGraph to another one is \e not allowed.
deba@2160
  1878
    void operator=(const ListBpUGraph &) {}
deba@2160
  1879
  public:
deba@2160
  1880
    /// \brief Constructor
deba@2160
  1881
    ///    
deba@2160
  1882
    /// Constructor.
deba@2160
  1883
    ///
deba@2160
  1884
    ListBpUGraph() {}
deba@2160
  1885
deba@2160
  1886
    typedef ExtendedListBpUGraphBase Parent;
deba@2160
  1887
    /// \brief Add a new ANode to the graph.
deba@2160
  1888
    ///
deba@2160
  1889
    /// \return the new node.
deba@2160
  1890
    ///
deba@2160
  1891
    Node addANode() { return Parent::addANode(); }
deba@2160
  1892
deba@2160
  1893
    /// \brief Add a new BNode to the graph.
deba@2160
  1894
    ///
deba@2160
  1895
    /// \return the new node.
deba@2160
  1896
    ///
deba@2160
  1897
    Node addBNode() { return Parent::addBNode(); }
deba@2160
  1898
deba@2160
  1899
    /// \brief Add a new edge to the graph.
deba@2160
  1900
    ///
deba@2160
  1901
    /// Add a new edge to the graph with an ANode and a BNode.
deba@2160
  1902
    /// \return the new undirected edge.
deba@2160
  1903
    UEdge addEdge(const Node& s, const Node& t) { 
deba@2160
  1904
      return Parent::addEdge(s, t); 
deba@2160
  1905
    }
deba@2160
  1906
deba@2160
  1907
    /// \brief Changes the ANode of \c e to \c n
deba@2160
  1908
    ///
deba@2160
  1909
    /// Changes the ANode of \c e to \c n
deba@2160
  1910
    ///
deba@2160
  1911
    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
deba@2160
  1912
    ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
deba@2160
  1913
    ///invalidated.
deba@2160
  1914
    void changeANode(UEdge e, Node n) { 
deba@2160
  1915
      Parent::changeANode(e,n); 
deba@2160
  1916
    }
deba@2160
  1917
deba@2160
  1918
    /// \brief Changes the BNode of \c e to \c n
deba@2160
  1919
    ///
deba@2160
  1920
    /// Changes the BNode of \c e to \c n
deba@2160
  1921
    ///
deba@2160
  1922
    /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
deba@2160
  1923
    /// referencing the changed edge remain
deba@2160
  1924
    /// valid. However <tt>InEdgeIt</tt>s are invalidated.
deba@2160
  1925
    void changeBNode(UEdge e, Node n) { 
deba@2160
  1926
      Parent::changeBNode(e,n); 
deba@2160
  1927
    }
deba@2160
  1928
deba@2160
  1929
    /// \brief Changes the source(ANode) of \c e to \c n
deba@2160
  1930
    ///
deba@2160
  1931
    /// Changes the source(ANode) of \c e to \c n
deba@2160
  1932
    ///
deba@2160
  1933
    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s referencing
deba@2160
  1934
    ///the changed edge remain valid. However <tt>OutEdgeIt</tt>s are
deba@2160
  1935
    ///invalidated.
deba@2160
  1936
    void changeSource(UEdge e, Node n) { 
deba@2160
  1937
      Parent::changeANode(e,n); 
deba@2160
  1938
    }
deba@2160
  1939
deba@2160
  1940
    /// \brief Changes the target(BNode) of \c e to \c n
deba@2160
  1941
    ///
deba@2160
  1942
    /// Changes the target(BNode) of \c e to \c n
deba@2160
  1943
    ///
deba@2160
  1944
    /// \note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
deba@2160
  1945
    /// referencing the changed edge remain
deba@2160
  1946
    /// valid. However <tt>InEdgeIt</tt>s are invalidated.
deba@2160
  1947
    void changeTarget(UEdge e, Node n) { 
deba@2160
  1948
      Parent::changeBNode(e,n); 
deba@2160
  1949
    }
deba@2160
  1950
deba@2160
  1951
    /// \brief Changes the source of \c e to \c n
deba@2160
  1952
    ///
deba@2160
  1953
    /// Changes the source of \c e to \c n. It changes the proper
deba@2160
  1954
    /// node of the represented undirected edge.
deba@2160
  1955
    ///
deba@2160
  1956
    ///\note The <tt>EdgeIt</tt>s and <tt>InEdgeIt</tt>s
deba@2160
  1957
    ///referencing the changed edge remain
deba@2160
  1958
    ///valid. However <tt>OutEdgeIt</tt>s are invalidated.
deba@2160
  1959
    void changeSource(Edge e, Node n) { 
deba@2160
  1960
      if (Parent::direction(e)) {
deba@2160
  1961
        Parent::changeANode(e,n);
deba@2160
  1962
      } else {
deba@2160
  1963
        Parent::changeBNode(e,n);
deba@2160
  1964
      } 
deba@2160
  1965
    }
deba@2160
  1966
    /// \brief Changes the target of \c e to \c n
deba@2160
  1967
    ///
deba@2160
  1968
    /// Changes the target of \c e to \c n. It changes the proper
deba@2160
  1969
    /// node of the represented undirected edge.
deba@2160
  1970
    ///
deba@2160
  1971
    ///\note The <tt>EdgeIt</tt>s and <tt>OutEdgeIt</tt>s
deba@2160
  1972
    ///referencing the changed edge remain
deba@2160
  1973
    ///valid. However <tt>InEdgeIt</tt>s are invalidated.
deba@2160
  1974
    void changeTarget(Edge e, Node n) { 
deba@2160
  1975
      if (Parent::direction(e)) {
deba@2160
  1976
        Parent::changeBNode(e,n);
deba@2160
  1977
      } else {
deba@2160
  1978
        Parent::changeANode(e,n);
deba@2160
  1979
      } 
deba@2160
  1980
    }
deba@2160
  1981
    /// \brief Contract two nodes.
deba@2160
  1982
    ///
deba@2160
  1983
    /// This function contracts two nodes.
deba@2160
  1984
    ///
deba@2160
  1985
    /// Node \p b will be removed but instead of deleting its
deba@2160
  1986
    /// neighboring edges, they will be joined to \p a.  The two nodes
deba@2160
  1987
    /// should be from the same nodeset, of course.
deba@2160
  1988
    ///
deba@2160
  1989
    /// \note The <tt>EdgeIt</tt>s referencing a moved edge remain
deba@2160
  1990
    /// valid.
deba@2160
  1991
    void contract(const Node& a, const Node& b) {
deba@2160
  1992
      LEMON_ASSERT(Parent::aNode(a) == Parent::aNode(b), NodeSetError());
deba@2160
  1993
      if (Parent::aNode(a)) {
deba@2160
  1994
        for (IncEdgeIt e(*this, b); e!=INVALID;) {
deba@2160
  1995
          IncEdgeIt f = e; ++f;
deba@2160
  1996
          changeSource(e, a);
deba@2160
  1997
          e = f;
deba@2160
  1998
        }
deba@2160
  1999
      } else {
deba@2160
  2000
        for (IncEdgeIt e(*this, b); e!=INVALID;) {
deba@2160
  2001
          IncEdgeIt f = e; ++f;
deba@2160
  2002
          changeTarget(e, a);
deba@2160
  2003
          e = f;
deba@2160
  2004
        }
deba@2160
  2005
      }
deba@2160
  2006
      erase(b);
deba@2160
  2007
    }
deba@2160
  2008
deba@2189
  2009
    /// \brief Class to make a snapshot of the graph and restore
deba@2189
  2010
    /// to it later.
deba@2189
  2011
    ///
deba@2189
  2012
    /// Class to make a snapshot of the graph and to restore it
deba@2189
  2013
    /// later.
deba@2189
  2014
    ///
deba@2189
  2015
    /// The newly added nodes and undirected edges can be removed
deba@2189
  2016
    /// using the restore() function.
deba@2189
  2017
    ///
deba@2189
  2018
    /// \warning Edge and node deletions cannot be restored. This
deba@2189
  2019
    /// events invalidate the snapshot. 
deba@2189
  2020
    class Snapshot {
deba@2189
  2021
    protected:
deba@2189
  2022
deba@2189
  2023
      typedef Parent::NodeNotifier NodeNotifier;
deba@2189
  2024
deba@2189
  2025
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
deba@2189
  2026
      public:
deba@2189
  2027
deba@2189
  2028
        NodeObserverProxy(Snapshot& _snapshot)
deba@2189
  2029
          : snapshot(_snapshot) {}
deba@2189
  2030
deba@2189
  2031
        using NodeNotifier::ObserverBase::attach;
deba@2189
  2032
        using NodeNotifier::ObserverBase::detach;
deba@2189
  2033
        using NodeNotifier::ObserverBase::attached;
deba@2189
  2034
        
deba@2189
  2035
      protected:
deba@2189
  2036
        
deba@2189
  2037
        virtual void add(const Node& node) {
deba@2189
  2038
          snapshot.addNode(node);
deba@2189
  2039
        }
deba@2189
  2040
        virtual void add(const std::vector<Node>& nodes) {
deba@2189
  2041
          for (int i = nodes.size() - 1; i >= 0; ++i) {
deba@2189
  2042
            snapshot.addNode(nodes[i]);
deba@2189
  2043
          }
deba@2189
  2044
        }
deba@2189
  2045
        virtual void erase(const Node& node) {
deba@2189
  2046
          snapshot.eraseNode(node);
deba@2189
  2047
        }
deba@2189
  2048
        virtual void erase(const std::vector<Node>& nodes) {
deba@2386
  2049
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@2189
  2050
            snapshot.eraseNode(nodes[i]);
deba@2189
  2051
          }
deba@2189
  2052
        }
deba@2189
  2053
        virtual void build() {
deba@2189
  2054
          Node node;
deba@2189
  2055
          std::vector<Node> nodes;
deba@2386
  2056
          for (notifier()->first(node); node != INVALID; 
deba@2386
  2057
               notifier()->next(node)) {
deba@2189
  2058
            nodes.push_back(node);
deba@2189
  2059
          }
deba@2189
  2060
          for (int i = nodes.size() - 1; i >= 0; --i) {
deba@2189
  2061
            snapshot.addNode(nodes[i]);
deba@2189
  2062
          }
deba@2189
  2063
        }
deba@2189
  2064
        virtual void clear() {
deba@2189
  2065
          Node node;
deba@2386
  2066
          for (notifier()->first(node); node != INVALID; 
deba@2386
  2067
               notifier()->next(node)) {
deba@2189
  2068
            snapshot.eraseNode(node);
deba@2189
  2069
          }
deba@2189
  2070
        }
deba@2189
  2071
deba@2189
  2072
        Snapshot& snapshot;
deba@2189
  2073
      };
deba@2189
  2074
deba@2189
  2075
      class UEdgeObserverProxy : public UEdgeNotifier::ObserverBase {
deba@2189
  2076
      public:
deba@2189
  2077
deba@2189
  2078
        UEdgeObserverProxy(Snapshot& _snapshot)
deba@2189
  2079
          : snapshot(_snapshot) {}
deba@2189
  2080
deba@2189
  2081
        using UEdgeNotifier::ObserverBase::attach;
deba@2189
  2082
        using UEdgeNotifier::ObserverBase::detach;
deba@2189
  2083
        using UEdgeNotifier::ObserverBase::attached;
deba@2189
  2084
        
deba@2189
  2085
      protected:
deba@2189
  2086
deba@2189
  2087
        virtual void add(const UEdge& edge) {
deba@2189
  2088
          snapshot.addUEdge(edge);
deba@2189
  2089
        }
deba@2189
  2090
        virtual void add(const std::vector<UEdge>& edges) {
deba@2189
  2091
          for (int i = edges.size() - 1; i >= 0; ++i) {
deba@2189
  2092
            snapshot.addUEdge(edges[i]);
deba@2189
  2093
          }
deba@2189
  2094
        }
deba@2189
  2095
        virtual void erase(const UEdge& edge) {
deba@2189
  2096
          snapshot.eraseUEdge(edge);
deba@2189
  2097
        }
deba@2189
  2098
        virtual void erase(const std::vector<UEdge>& edges) {
deba@2386
  2099
          for (int i = 0; i < int(edges.size()); ++i) {
deba@2189
  2100
            snapshot.eraseUEdge(edges[i]);
deba@2189
  2101
          }
deba@2189
  2102
        }
deba@2189
  2103
        virtual void build() {
deba@2189
  2104
          UEdge edge;
deba@2189
  2105
          std::vector<UEdge> edges;
deba@2386
  2106
          for (notifier()->first(edge); edge != INVALID; 
deba@2386
  2107
               notifier()->next(edge)) {
deba@2189
  2108
            edges.push_back(edge);
deba@2189
  2109
          }
deba@2189
  2110
          for (int i = edges.size() - 1; i >= 0; --i) {
deba@2189
  2111
            snapshot.addUEdge(edges[i]);
deba@2189
  2112
          }
deba@2189
  2113
        }
deba@2189
  2114
        virtual void clear() {
deba@2189
  2115
          UEdge edge;
deba@2386
  2116
          for (notifier()->first(edge); edge != INVALID; 
deba@2386
  2117
               notifier()->next(edge)) {
deba@2189
  2118
            snapshot.eraseUEdge(edge);
deba@2189
  2119
          }
deba@2189
  2120
        }
deba@2189
  2121
deba@2189
  2122
        Snapshot& snapshot;
deba@2189
  2123
      };
deba@2189
  2124
      
deba@2189
  2125
      ListBpUGraph *graph;
deba@2189
  2126
deba@2189
  2127
      NodeObserverProxy node_observer_proxy;
deba@2189
  2128
      UEdgeObserverProxy edge_observer_proxy;
deba@2189
  2129
deba@2189
  2130
      std::list<Node> added_nodes;
deba@2189
  2131
      std::list<UEdge> added_edges;
deba@2189
  2132
deba@2189
  2133
deba@2189
  2134
      void addNode(const Node& node) {
deba@2189
  2135
        added_nodes.push_front(node);        
deba@2189
  2136
      }
deba@2189
  2137
      void eraseNode(const Node& node) {
deba@2189
  2138
        std::list<Node>::iterator it = 
deba@2189
  2139
          std::find(added_nodes.begin(), added_nodes.end(), node);
deba@2189
  2140
        if (it == added_nodes.end()) {
deba@2189
  2141
          clear();
deba@2189
  2142
          edge_observer_proxy.detach();
deba@2189
  2143
          throw NodeNotifier::ImmediateDetach();
deba@2189
  2144
        } else {
deba@2189
  2145
          added_nodes.erase(it);
deba@2189
  2146
        }
deba@2189
  2147
      }
deba@2189
  2148
deba@2189
  2149
      void addUEdge(const UEdge& edge) {
deba@2189
  2150
        added_edges.push_front(edge);        
deba@2189
  2151
      }
deba@2189
  2152
      void eraseUEdge(const UEdge& edge) {
deba@2189
  2153
        std::list<UEdge>::iterator it = 
deba@2189
  2154
          std::find(added_edges.begin(), added_edges.end(), edge);
deba@2189
  2155
        if (it == added_edges.end()) {
deba@2189
  2156
          clear();
deba@2189
  2157
          node_observer_proxy.detach();
deba@2189
  2158
          throw UEdgeNotifier::ImmediateDetach();
deba@2189
  2159
        } else {
deba@2189
  2160
          added_edges.erase(it);
deba@2189
  2161
        }        
deba@2189
  2162
      }
deba@2189
  2163
deba@2189
  2164
      void attach(ListBpUGraph &_graph) {
deba@2189
  2165
	graph = &_graph;
deba@2381
  2166
	node_observer_proxy.attach(graph->notifier(Node()));
deba@2381
  2167
        edge_observer_proxy.attach(graph->notifier(UEdge()));
deba@2189
  2168
      }
deba@2189
  2169
            
deba@2189
  2170
      void detach() {
deba@2189
  2171
	node_observer_proxy.detach();
deba@2189
  2172
	edge_observer_proxy.detach();
deba@2189
  2173
      }
deba@2189
  2174
deba@2189
  2175
      bool attached() const {
deba@2189
  2176
        return node_observer_proxy.attached();
deba@2189
  2177
      }
deba@2189
  2178
deba@2189
  2179
      void clear() {
deba@2189
  2180
        added_nodes.clear();
deba@2189
  2181
        added_edges.clear();        
deba@2189
  2182
      }
deba@2189
  2183
deba@2189
  2184
    public:
deba@2189
  2185
deba@2189
  2186
      /// \brief Default constructor.
deba@2189
  2187
      ///
deba@2189
  2188
      /// Default constructor.
deba@2189
  2189
      /// To actually make a snapshot you must call save().
deba@2189
  2190
      Snapshot() 
deba@2189
  2191
        : graph(0), node_observer_proxy(*this), 
deba@2189
  2192
          edge_observer_proxy(*this) {}
deba@2189
  2193
      
deba@2189
  2194
      /// \brief Constructor that immediately makes a snapshot.
deba@2189
  2195
      ///      
deba@2189
  2196
      /// This constructor immediately makes a snapshot of the graph.
deba@2189
  2197
      /// \param _graph The graph we make a snapshot of.
deba@2189
  2198
      Snapshot(ListBpUGraph &_graph) 
deba@2189
  2199
        : node_observer_proxy(*this), 
deba@2189
  2200
          edge_observer_proxy(*this) {
deba@2189
  2201
	attach(_graph);
deba@2189
  2202
      }
deba@2189
  2203
      
deba@2189
  2204
      /// \brief Make a snapshot.
deba@2189
  2205
      ///
deba@2189
  2206
      /// Make a snapshot of the graph.
deba@2189
  2207
      ///
deba@2189
  2208
      /// This function can be called more than once. In case of a repeated
deba@2189
  2209
      /// call, the previous snapshot gets lost.
deba@2189
  2210
      /// \param _graph The graph we make the snapshot of.
deba@2189
  2211
      void save(ListBpUGraph &_graph) {
deba@2189
  2212
        if (attached()) {
deba@2189
  2213
          detach();
deba@2189
  2214
          clear();
deba@2189
  2215
        }
deba@2189
  2216
        attach(_graph);
deba@2189
  2217
      }
deba@2189
  2218
      
deba@2189
  2219
      /// \brief Undo the changes until the last snapshot.
deba@2189
  2220
      // 
deba@2189
  2221
      /// Undo the changes until the last snapshot created by save().
deba@2189
  2222
      void restore() {
deba@2189
  2223
	detach();
deba@2189
  2224
	for(std::list<UEdge>::iterator it = added_edges.begin(); 
deba@2189
  2225
            it != added_edges.end(); ++it) {
deba@2189
  2226
	  graph->erase(*it);
deba@2189
  2227
	}
deba@2189
  2228
	for(std::list<Node>::iterator it = added_nodes.begin(); 
deba@2189
  2229
            it != added_nodes.end(); ++it) {
deba@2189
  2230
	  graph->erase(*it);
deba@2189
  2231
	}
deba@2189
  2232
        clear();
deba@2189
  2233
      }
deba@2189
  2234
deba@2189
  2235
      /// \brief Gives back true when the snapshot is valid.
deba@2189
  2236
      ///
deba@2189
  2237
      /// Gives back true when the snapshot is valid.
deba@2189
  2238
      bool valid() const {
deba@2189
  2239
        return attached();
deba@2189
  2240
      }
deba@2189
  2241
    };
deba@2160
  2242
  };
deba@2116
  2243
deba@2116
  2244
  
deba@2116
  2245
  /// @}  
alpar@948
  2246
} //namespace lemon
klao@946
  2247
  
alpar@400
  2248
klao@946
  2249
#endif