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