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