src/hugo/list_graph.h
author alpar
Thu, 23 Sep 2004 15:09:55 +0000
changeset 907 df8472ab5d4a
parent 905 5be029d19c98
child 909 6a22e0dfd453
permissions -rw-r--r--
I forgot to apply
for i in `ls *.h`; do rpl template.h $i $i; done
in src/hugo/attic
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 * src/hugo/list_graph.h - Part of HUGOlib, a generic C++ optimization library
alpar@906
     3
 *
alpar@906
     4
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@395
    16
alpar@405
    17
#ifndef HUGO_LIST_GRAPH_H
alpar@405
    18
#define HUGO_LIST_GRAPH_H
alpar@395
    19
klao@491
    20
///\ingroup graphs
alpar@395
    21
///\file
alpar@405
    22
///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
alpar@395
    23
alpar@395
    24
#include <vector>
deba@782
    25
#include <climits>
alpar@395
    26
ladanyi@542
    27
#include <hugo/invalid.h>
alpar@395
    28
deba@782
    29
#include <hugo/map_registry.h>
deba@897
    30
#include <hugo/array_map.h>
deba@782
    31
deba@822
    32
#include <hugo/sym_map.h>
deba@782
    33
deba@782
    34
#include <hugo/map_defines.h>
deba@782
    35
deba@782
    36
alpar@395
    37
namespace hugo {
alpar@395
    38
alpar@406
    39
/// \addtogroup graphs
alpar@406
    40
/// @{
alpar@406
    41
alpar@401
    42
  ///A list graph class.
alpar@395
    43
alpar@397
    44
  ///This is a simple and fast erasable graph implementation.
alpar@397
    45
  ///
alpar@880
    46
  ///It conforms to the
alpar@880
    47
  ///\ref skeleton::ErasableGraph "ErasableGraph" concept.
alpar@880
    48
  ///\sa skeleton::ErasableGraph.
alpar@397
    49
  class ListGraph {
alpar@395
    50
alpar@397
    51
    //Nodes are double linked.
alpar@397
    52
    //The free nodes are only single linked using the "next" field.
alpar@395
    53
    struct NodeT 
alpar@395
    54
    {
alpar@397
    55
      int first_in,first_out;
alpar@397
    56
      int prev, next;
alpar@395
    57
    };
alpar@397
    58
    //Edges are double linked.
alpar@397
    59
    //The free edges are only single linked using the "next_in" field.
alpar@395
    60
    struct EdgeT 
alpar@395
    61
    {
alpar@397
    62
      int head, tail;
alpar@397
    63
      int prev_in, prev_out;
alpar@397
    64
      int next_in, next_out;
alpar@395
    65
    };
alpar@395
    66
alpar@395
    67
    std::vector<NodeT> nodes;
alpar@397
    68
    //The first node
alpar@397
    69
    int first_node;
alpar@397
    70
    //The first free node
alpar@397
    71
    int first_free_node;
alpar@395
    72
    std::vector<EdgeT> edges;
alpar@397
    73
    //The first free edge
alpar@397
    74
    int first_free_edge;
alpar@395
    75
    
deba@782
    76
  public:
alpar@395
    77
    
deba@782
    78
    typedef ListGraph Graph;
alpar@397
    79
    
alpar@395
    80
    class Node;
alpar@395
    81
    class Edge;
alpar@395
    82
alpar@395
    83
    
alpar@395
    84
  public:
alpar@395
    85
alpar@395
    86
    class NodeIt;
alpar@395
    87
    class EdgeIt;
alpar@395
    88
    class OutEdgeIt;
alpar@395
    89
    class InEdgeIt;
deba@782
    90
alpar@904
    91
    // Create map registries.
deba@782
    92
    CREATE_MAP_REGISTRIES;
alpar@905
    93
    // Create node and edge maps.
deba@897
    94
    CREATE_MAPS(ArrayMap);
deba@782
    95
alpar@395
    96
  public:
alpar@395
    97
deba@782
    98
    ListGraph() 
deba@782
    99
      : nodes(), first_node(-1),
deba@782
   100
	first_free_node(-1), edges(), first_free_edge(-1) {}
deba@782
   101
deba@782
   102
    ListGraph(const ListGraph &_g) 
deba@782
   103
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   104
	first_free_node(_g.first_free_node), edges(_g.edges),
deba@782
   105
	first_free_edge(_g.first_free_edge) {}
alpar@395
   106
    
alpar@813
   107
    ///Number of nodes.
alpar@813
   108
    int nodeNum() const { return nodes.size(); }
alpar@813
   109
    ///Number of edges.
alpar@813
   110
    int edgeNum() const { return edges.size(); }
alpar@395
   111
alpar@813
   112
    ///Set the expected maximum number of edges.
alpar@695
   113
alpar@695
   114
    ///With this function, it is possible to set the expected number of edges.
alpar@695
   115
    ///The use of this fasten the building of the graph and makes
alpar@695
   116
    ///it possible to avoid the superfluous memory allocation.
alpar@695
   117
    void reserveEdge(int n) { edges.reserve(n); };
alpar@695
   118
    
alpar@813
   119
    /// Maximum node ID.
alpar@813
   120
    
alpar@813
   121
    /// Maximum node ID.
alpar@813
   122
    ///\sa id(Node)
alpar@813
   123
    int maxNodeId() const { return nodes.size()-1; } 
alpar@813
   124
    /// Maximum edge ID.
alpar@813
   125
    
alpar@813
   126
    /// Maximum edge ID.
alpar@813
   127
    ///\sa id(Edge)
alpar@813
   128
    int maxEdgeId() const { return edges.size()-1; }
alpar@395
   129
alpar@395
   130
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@395
   131
    Node head(Edge e) const { return edges[e.n].head; }
alpar@395
   132
alpar@713
   133
    NodeIt& first(NodeIt& v) const { 
alpar@395
   134
      v=NodeIt(*this); return v; }
alpar@713
   135
    EdgeIt& first(EdgeIt& e) const { 
alpar@395
   136
      e=EdgeIt(*this); return e; }
alpar@713
   137
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@395
   138
      e=OutEdgeIt(*this,v); return e; }
alpar@713
   139
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@395
   140
      e=InEdgeIt(*this,v); return e; }
alpar@395
   141
alpar@813
   142
    /// Node ID.
alpar@813
   143
    
alpar@813
   144
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   145
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   146
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   147
    ///
alpar@813
   148
    /// The ID of the \ref INVALID node is -1.
alpar@813
   149
    ///\return The ID of the node \c v. 
alpar@713
   150
    static int id(Node v) { return v.n; }
alpar@813
   151
    /// Edge ID.
alpar@813
   152
    
alpar@813
   153
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   154
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   155
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   156
    ///
alpar@813
   157
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   158
    ///\return The ID of the edge \c e. 
alpar@713
   159
    static int id(Edge e) { return e.n; }
alpar@395
   160
alpar@397
   161
    /// Adds a new node to the graph.
alpar@397
   162
alpar@813
   163
    /// \warning It adds the new node to the front of the list.
alpar@397
   164
    /// (i.e. the lastly added node becomes the first.)
alpar@395
   165
    Node addNode() {
alpar@397
   166
      int n;
alpar@397
   167
      
alpar@397
   168
      if(first_free_node==-1)
alpar@397
   169
	{
alpar@397
   170
	  n = nodes.size();
alpar@397
   171
	  nodes.push_back(NodeT());
alpar@397
   172
	}
alpar@397
   173
      else {
alpar@397
   174
	n = first_free_node;
alpar@397
   175
	first_free_node = nodes[n].next;
alpar@397
   176
      }
alpar@397
   177
      
alpar@397
   178
      nodes[n].next = first_node;
alpar@397
   179
      if(first_node != -1) nodes[first_node].prev = n;
alpar@397
   180
      first_node = n;
alpar@397
   181
      nodes[n].prev = -1;
alpar@397
   182
      
alpar@397
   183
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@397
   184
      
alpar@397
   185
      Node nn; nn.n=n;
alpar@395
   186
alpar@397
   187
      //Update dynamic maps
deba@782
   188
      node_maps.add(nn);
alpar@395
   189
alpar@397
   190
      return nn;
alpar@395
   191
    }
alpar@395
   192
    
alpar@395
   193
    Edge addEdge(Node u, Node v) {
alpar@397
   194
      int n;
alpar@397
   195
      
alpar@397
   196
      if(first_free_edge==-1)
alpar@397
   197
	{
alpar@397
   198
	  n = edges.size();
alpar@397
   199
	  edges.push_back(EdgeT());
alpar@397
   200
	}
alpar@397
   201
      else {
alpar@397
   202
	n = first_free_edge;
alpar@397
   203
	first_free_edge = edges[n].next_in;
alpar@397
   204
      }
alpar@397
   205
      
alpar@397
   206
      edges[n].tail = u.n; edges[n].head = v.n;
alpar@395
   207
alpar@397
   208
      edges[n].next_out = nodes[u.n].first_out;
alpar@397
   209
      if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
alpar@397
   210
      edges[n].next_in = nodes[v.n].first_in;
alpar@397
   211
      if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
alpar@397
   212
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@397
   213
	
alpar@397
   214
      nodes[u.n].first_out = nodes[v.n].first_in = n;
alpar@397
   215
alpar@397
   216
      Edge e; e.n=n;
alpar@397
   217
alpar@397
   218
      //Update dynamic maps
deba@782
   219
      edge_maps.add(e);
alpar@395
   220
alpar@395
   221
      return e;
alpar@395
   222
    }
alpar@774
   223
    
alpar@774
   224
    /// Finds an edge between two nodes.
alpar@395
   225
alpar@774
   226
    /// Finds an edge from node \c u to node \c v.
alpar@774
   227
    ///
alpar@774
   228
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
   229
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
   230
    /// the next edge from \c u to \c v after \c prev.
alpar@774
   231
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
   232
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   233
    {
alpar@774
   234
      int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
alpar@774
   235
      while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
alpar@774
   236
      prev.n=e;
alpar@774
   237
      return prev;
alpar@774
   238
    }
alpar@774
   239
    
alpar@397
   240
  private:
alpar@397
   241
    void eraseEdge(int n) {
alpar@397
   242
      
alpar@397
   243
      if(edges[n].next_in!=-1)
alpar@397
   244
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@397
   245
      if(edges[n].prev_in!=-1)
alpar@397
   246
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@397
   247
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@397
   248
      
alpar@397
   249
      if(edges[n].next_out!=-1)
alpar@397
   250
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@397
   251
      if(edges[n].prev_out!=-1)
alpar@397
   252
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@397
   253
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@397
   254
      
alpar@397
   255
      edges[n].next_in = first_free_edge;
alpar@695
   256
      first_free_edge = n;      
alpar@397
   257
alpar@397
   258
      //Update dynamic maps
alpar@397
   259
      Edge e; e.n=n;
deba@782
   260
      edge_maps.erase(e);
deba@782
   261
alpar@397
   262
    }
alpar@397
   263
      
alpar@397
   264
  public:
alpar@397
   265
alpar@397
   266
    void erase(Node nn) {
alpar@397
   267
      int n=nn.n;
alpar@397
   268
      
alpar@397
   269
      int m;
alpar@397
   270
      while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@397
   271
      while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@397
   272
alpar@397
   273
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@397
   274
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@397
   275
      else first_node = nodes[n].next;
alpar@397
   276
      
alpar@397
   277
      nodes[n].next = first_free_node;
alpar@397
   278
      first_free_node = n;
alpar@397
   279
alpar@397
   280
      //Update dynamic maps
deba@782
   281
      node_maps.erase(nn);
deba@782
   282
alpar@397
   283
    }
alpar@397
   284
    
alpar@397
   285
    void erase(Edge e) { eraseEdge(e.n); }
alpar@397
   286
alpar@397
   287
    void clear() {
deba@782
   288
      edge_maps.clear();
deba@782
   289
      edges.clear();
deba@782
   290
      node_maps.clear();
deba@782
   291
      nodes.clear();
alpar@397
   292
      first_node=first_free_node=first_free_edge=-1;
alpar@397
   293
    }
alpar@395
   294
alpar@395
   295
    class Node {
alpar@397
   296
      friend class ListGraph;
alpar@395
   297
      template <typename T> friend class NodeMap;
alpar@400
   298
       
alpar@395
   299
      friend class Edge;
alpar@395
   300
      friend class OutEdgeIt;
alpar@395
   301
      friend class InEdgeIt;
alpar@395
   302
      friend class SymEdge;
alpar@395
   303
alpar@395
   304
    protected:
alpar@395
   305
      int n;
alpar@722
   306
      friend int ListGraph::id(Node v); 
alpar@395
   307
      Node(int nn) {n=nn;}
alpar@395
   308
    public:
alpar@395
   309
      Node() {}
alpar@503
   310
      Node (Invalid) { n=-1; }
alpar@395
   311
      bool operator==(const Node i) const {return n==i.n;}
alpar@395
   312
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@395
   313
      bool operator<(const Node i) const {return n<i.n;}
alpar@774
   314
      //      ///Validity check
alpar@774
   315
      //      operator bool() { return n!=-1; }
alpar@395
   316
    };
alpar@395
   317
    
alpar@395
   318
    class NodeIt : public Node {
alpar@774
   319
      const ListGraph *G;
alpar@397
   320
      friend class ListGraph;
alpar@395
   321
    public:
alpar@400
   322
      NodeIt() : Node() { }
alpar@400
   323
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   324
      NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
   325
      NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
alpar@774
   326
      NodeIt &operator++() {
alpar@774
   327
	n=G->nodes[n].next; 
alpar@774
   328
	return *this; 
alpar@774
   329
      }
alpar@774
   330
      //      ///Validity check
alpar@774
   331
      //      operator bool() { return Node::operator bool(); }      
alpar@395
   332
    };
alpar@395
   333
alpar@395
   334
    class Edge {
alpar@397
   335
      friend class ListGraph;
alpar@395
   336
      template <typename T> friend class EdgeMap;
alpar@395
   337
alpar@905
   338
      friend class SymListGraph;
alpar@395
   339
      
alpar@395
   340
      friend class Node;
alpar@395
   341
      friend class NodeIt;
alpar@395
   342
    protected:
alpar@395
   343
      int n;
alpar@722
   344
      friend int ListGraph::id(Edge e);
alpar@395
   345
alpar@706
   346
    public:
alpar@706
   347
      /// An Edge with id \c n.
alpar@706
   348
alpar@706
   349
      /// \bug It should be
alpar@706
   350
      /// obtained by a member function of the Graph.
alpar@395
   351
      Edge(int nn) {n=nn;}
alpar@706
   352
alpar@395
   353
      Edge() { }
alpar@395
   354
      Edge (Invalid) { n=-1; }
alpar@395
   355
      bool operator==(const Edge i) const {return n==i.n;}
alpar@395
   356
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@395
   357
      bool operator<(const Edge i) const {return n<i.n;}
alpar@774
   358
      //      ///Validity check
alpar@774
   359
      //      operator bool() { return n!=-1; }
alpar@774
   360
   };
alpar@395
   361
    
alpar@395
   362
    class EdgeIt : public Edge {
alpar@774
   363
      const ListGraph *G;
alpar@397
   364
      friend class ListGraph;
alpar@395
   365
    public:
alpar@774
   366
      EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
alpar@397
   367
      	int m;
alpar@774
   368
	for(m=_G.first_node;
alpar@774
   369
	    m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
alpar@774
   370
	n = (m==-1)?-1:_G.nodes[m].first_in;
alpar@397
   371
      }
alpar@395
   372
      EdgeIt (Invalid i) : Edge(i) { }
alpar@774
   373
      EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   374
      EdgeIt() : Edge() { }
alpar@774
   375
      EdgeIt &operator++() {
alpar@774
   376
	if(G->edges[n].next_in!=-1) n=G->edges[n].next_in;
alpar@774
   377
	else {
alpar@774
   378
	  int nn;
alpar@774
   379
	  for(nn=G->nodes[G->edges[n].head].next;
alpar@774
   380
	      nn!=-1 && G->nodes[nn].first_in == -1;
alpar@774
   381
	      nn = G->nodes[nn].next) ;
alpar@774
   382
	  n = (nn==-1)?-1:G->nodes[nn].first_in;
alpar@774
   383
	}
alpar@774
   384
	return *this;
alpar@774
   385
      }
alpar@774
   386
      //      ///Validity check
alpar@774
   387
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   388
    };
alpar@395
   389
    
alpar@395
   390
    class OutEdgeIt : public Edge {
alpar@774
   391
      const ListGraph *G;
alpar@397
   392
      friend class ListGraph;
alpar@395
   393
    public: 
alpar@395
   394
      OutEdgeIt() : Edge() { }
alpar@774
   395
      OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   396
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@395
   397
alpar@774
   398
      OutEdgeIt(const ListGraph& _G,const Node v)
alpar@774
   399
	: Edge(_G.nodes[v.n].first_out), G(&_G) {}
alpar@774
   400
      OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; }
alpar@774
   401
      //      ///Validity check
alpar@774
   402
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   403
    };
alpar@395
   404
    
alpar@395
   405
    class InEdgeIt : public Edge {
alpar@774
   406
      const ListGraph *G;
alpar@397
   407
      friend class ListGraph;
alpar@395
   408
    public: 
alpar@395
   409
      InEdgeIt() : Edge() { }
alpar@774
   410
      InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   411
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
   412
      InEdgeIt(const ListGraph& _G,Node v)
alpar@774
   413
	: Edge(_G.nodes[v.n].first_in), G(&_G) { }
alpar@774
   414
      InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
alpar@774
   415
      //      ///Validity check
alpar@774
   416
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   417
    };
alpar@395
   418
  };
alpar@395
   419
alpar@395
   420
  ///Graph for bidirectional edges.
alpar@395
   421
alpar@395
   422
  ///The purpose of this graph structure is to handle graphs
alpar@395
   423
  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
alpar@395
   424
  ///of oppositely directed edges.
alpar@395
   425
  ///There is a new edge map type called
alpar@397
   426
  ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
alpar@395
   427
  ///that complements this
alpar@395
   428
  ///feature by
alpar@395
   429
  ///storing shared values for the edge pairs. The usual
alpar@880
   430
  ///\ref Graph::EdgeMap "EdgeMap"
alpar@395
   431
  ///can be used
alpar@395
   432
  ///as well.
alpar@395
   433
  ///
alpar@395
   434
  ///The oppositely directed edge can also be obtained easily
alpar@395
   435
  ///using \ref opposite.
alpar@397
   436
  ///
alpar@397
   437
  ///Here erase(Edge) deletes a pair of edges.
alpar@397
   438
  ///
alpar@397
   439
  ///\todo this date structure need some reconsiderations. Maybe it
alpar@397
   440
  ///should be implemented independently from ListGraph.
deba@782
   441
  
alpar@397
   442
  class SymListGraph : public ListGraph
alpar@395
   443
  {
alpar@395
   444
  public:
deba@782
   445
deba@782
   446
    typedef SymListGraph Graph;
deba@782
   447
alpar@904
   448
    // Create symmetric map registry.
deba@782
   449
    CREATE_SYM_EDGE_MAP_REGISTRY;
alpar@904
   450
    // Create symmetric edge map.
deba@897
   451
    CREATE_SYM_EDGE_MAP(ArrayMap);
alpar@395
   452
alpar@397
   453
    SymListGraph() : ListGraph() { }
alpar@397
   454
    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
alpar@397
   455
    ///Adds a pair of oppositely directed edges to the graph.
alpar@395
   456
    Edge addEdge(Node u, Node v)
alpar@395
   457
    {
alpar@397
   458
      Edge e = ListGraph::addEdge(u,v);
deba@782
   459
      Edge f = ListGraph::addEdge(v,u);
deba@782
   460
      sym_edge_maps.add(e);
deba@782
   461
      sym_edge_maps.add(f);
deba@782
   462
      
alpar@395
   463
      return e;
alpar@395
   464
    }
alpar@395
   465
deba@782
   466
    void erase(Node n) { ListGraph::erase(n);}
alpar@395
   467
    ///The oppositely directed edge.
alpar@395
   468
alpar@395
   469
    ///Returns the oppositely directed
alpar@395
   470
    ///pair of the edge \c e.
alpar@713
   471
    static Edge opposite(Edge e)
alpar@395
   472
    {
alpar@395
   473
      Edge f;
alpar@905
   474
      f.n = e.n - 2*(e.n%2) + 1;
alpar@395
   475
      return f;
alpar@395
   476
    }
alpar@395
   477
    
alpar@397
   478
    ///Removes a pair of oppositely directed edges to the graph.
alpar@397
   479
    void erase(Edge e) {
deba@782
   480
      Edge f = opposite(e);
deba@782
   481
      sym_edge_maps.erase(e);
deba@782
   482
      sym_edge_maps.erase(f);
deba@782
   483
      ListGraph::erase(f);
alpar@397
   484
      ListGraph::erase(e);
deba@782
   485
    }    
deba@782
   486
  };
alpar@395
   487
alpar@400
   488
alpar@401
   489
  ///A graph class containing only nodes.
alpar@400
   490
alpar@401
   491
  ///This class implements a graph structure without edges.
alpar@401
   492
  ///The most useful application of this class is to be the node set of an
alpar@401
   493
  ///\ref EdgeSet class.
alpar@400
   494
  ///
alpar@880
   495
  ///It conforms to 
alpar@880
   496
  ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept
alpar@880
   497
  ///with the exception that you cannot
alpar@401
   498
  ///add (or delete) edges. The usual edge iterators are exists, but they are
alpar@401
   499
  ///always \ref INVALID.
alpar@880
   500
  ///\sa skeleton::ExtendableGraph
alpar@880
   501
  ///\sa EdgeSet
alpar@400
   502
  class NodeSet {
alpar@400
   503
alpar@400
   504
    //Nodes are double linked.
alpar@400
   505
    //The free nodes are only single linked using the "next" field.
alpar@400
   506
    struct NodeT 
alpar@400
   507
    {
alpar@400
   508
      int first_in,first_out;
alpar@400
   509
      int prev, next;
alpar@400
   510
      //      NodeT() {}
alpar@400
   511
    };
alpar@400
   512
alpar@400
   513
    std::vector<NodeT> nodes;
alpar@400
   514
    //The first node
alpar@400
   515
    int first_node;
alpar@400
   516
    //The first free node
alpar@400
   517
    int first_free_node;
alpar@400
   518
    
alpar@400
   519
  public:
deba@782
   520
deba@782
   521
    typedef NodeSet Graph;
alpar@400
   522
    
alpar@400
   523
    class Node;
alpar@400
   524
    class Edge;
alpar@400
   525
alpar@400
   526
  public:
alpar@400
   527
alpar@400
   528
    class NodeIt;
alpar@400
   529
    class EdgeIt;
alpar@400
   530
    class OutEdgeIt;
alpar@400
   531
    class InEdgeIt;
alpar@400
   532
    
alpar@904
   533
    // Create node map registry.
deba@822
   534
    CREATE_NODE_MAP_REGISTRY;
alpar@904
   535
    // Create node maps.
deba@897
   536
    CREATE_NODE_MAP(ArrayMap);
deba@822
   537
deba@822
   538
    /// Creating empty map structure for edges.
deba@822
   539
    template <typename Value>
deba@822
   540
    class EdgeMap {
deba@822
   541
    public:
deba@822
   542
      EdgeMap(const Graph&) {}
deba@822
   543
      EdgeMap(const Graph&, const Value&) {}
deba@822
   544
deba@822
   545
      EdgeMap(const EdgeMap&) {}
deba@822
   546
      template <typename CMap> EdgeMap(const CMap&) {}
deba@822
   547
deba@822
   548
      EdgeMap& operator=(const EdgeMap&) {}
deba@822
   549
      template <typename CMap> EdgeMap& operator=(const CMap&) {}
deba@822
   550
      
deba@822
   551
      class ConstIterator {
deba@822
   552
      public:
deba@822
   553
	bool operator==(const ConstIterator&) {return true;}
deba@822
   554
	bool operator!=(const ConstIterator&) {return false;}
deba@822
   555
      };
deba@822
   556
deba@822
   557
      typedef ConstIterator Iterator;
deba@822
   558
      
deba@822
   559
      Iterator begin() { return Iterator();}
deba@822
   560
      Iterator end() { return Iterator();}
deba@822
   561
deba@822
   562
      ConstIterator begin() const { return ConstIterator();}
deba@822
   563
      ConstIterator end() const { return ConstIterator();}
deba@822
   564
deba@822
   565
    };
alpar@400
   566
    
alpar@400
   567
  public:
alpar@400
   568
alpar@408
   569
    ///Default constructor
deba@782
   570
    NodeSet() 
deba@782
   571
      : nodes(), first_node(-1), first_free_node(-1) {}
alpar@408
   572
    ///Copy constructor
deba@782
   573
    NodeSet(const NodeSet &_g) 
deba@782
   574
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   575
	first_free_node(_g.first_free_node) {}
alpar@400
   576
    
alpar@813
   577
    ///Number of nodes.
alpar@813
   578
    int nodeNum() const { return nodes.size(); }
alpar@813
   579
    ///Number of edges.
alpar@813
   580
    int edgeNum() const { return 0; }
alpar@400
   581
alpar@813
   582
    /// Maximum node ID.
alpar@813
   583
    
alpar@813
   584
    /// Maximum node ID.
alpar@813
   585
    ///\sa id(Node)
alpar@813
   586
    int maxNodeId() const { return nodes.size()-1; }
alpar@813
   587
    /// Maximum edge ID.
alpar@813
   588
    
alpar@813
   589
    /// Maximum edge ID.
alpar@813
   590
    ///\sa id(Edge)
alpar@813
   591
    int maxEdgeId() const { return 0; }
alpar@400
   592
alpar@400
   593
    Node tail(Edge e) const { return INVALID; }
alpar@400
   594
    Node head(Edge e) const { return INVALID; }
alpar@400
   595
alpar@400
   596
    NodeIt& first(NodeIt& v) const { 
alpar@400
   597
      v=NodeIt(*this); return v; }
alpar@400
   598
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   599
      e=EdgeIt(*this); return e; }
alpar@400
   600
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   601
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   602
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   603
      e=InEdgeIt(*this,v); return e; }
alpar@400
   604
alpar@813
   605
    /// Node ID.
alpar@813
   606
    
alpar@813
   607
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   608
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   609
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   610
    ///
alpar@813
   611
    /// The ID of the \ref INVALID node is -1.
alpar@813
   612
    ///\return The ID of the node \c v. 
alpar@905
   613
    static int id(Node v) { return v.n; }
alpar@813
   614
    /// Edge ID.
alpar@813
   615
    
alpar@813
   616
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   617
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   618
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   619
    ///
alpar@813
   620
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   621
    ///\return The ID of the edge \c e. 
alpar@905
   622
    static int id(Edge e) { return -1; }
alpar@400
   623
alpar@400
   624
    /// Adds a new node to the graph.
alpar@400
   625
alpar@813
   626
    /// \warning It adds the new node to the front of the list.
alpar@400
   627
    /// (i.e. the lastly added node becomes the first.)
alpar@400
   628
    Node addNode() {
alpar@400
   629
      int n;
alpar@400
   630
      
alpar@400
   631
      if(first_free_node==-1)
alpar@400
   632
	{
alpar@400
   633
	  n = nodes.size();
alpar@400
   634
	  nodes.push_back(NodeT());
alpar@400
   635
	}
alpar@400
   636
      else {
alpar@400
   637
	n = first_free_node;
alpar@400
   638
	first_free_node = nodes[n].next;
alpar@400
   639
      }
alpar@400
   640
      
alpar@400
   641
      nodes[n].next = first_node;
alpar@400
   642
      if(first_node != -1) nodes[first_node].prev = n;
alpar@400
   643
      first_node = n;
alpar@400
   644
      nodes[n].prev = -1;
alpar@400
   645
      
alpar@400
   646
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@400
   647
      
alpar@400
   648
      Node nn; nn.n=n;
alpar@400
   649
alpar@400
   650
      //Update dynamic maps
deba@782
   651
      node_maps.add(nn);
alpar@400
   652
alpar@400
   653
      return nn;
alpar@400
   654
    }
alpar@400
   655
    
alpar@400
   656
    void erase(Node nn) {
alpar@400
   657
      int n=nn.n;
alpar@400
   658
      
alpar@400
   659
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@400
   660
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@400
   661
      else first_node = nodes[n].next;
alpar@400
   662
      
alpar@400
   663
      nodes[n].next = first_free_node;
alpar@400
   664
      first_free_node = n;
alpar@400
   665
alpar@400
   666
      //Update dynamic maps
deba@782
   667
      node_maps.erase(nn);
alpar@400
   668
    }
alpar@400
   669
    
alpar@774
   670
        
alpar@774
   671
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   672
    {
alpar@774
   673
      return INVALID;
alpar@774
   674
    }
alpar@774
   675
    
alpar@400
   676
    void clear() {
deba@782
   677
      node_maps.clear();
alpar@400
   678
      nodes.clear();
alpar@400
   679
      first_node = first_free_node = -1;
alpar@400
   680
    }
alpar@400
   681
alpar@400
   682
    class Node {
alpar@400
   683
      friend class NodeSet;
alpar@400
   684
      template <typename T> friend class NodeMap;
alpar@400
   685
      
alpar@400
   686
      friend class Edge;
alpar@400
   687
      friend class OutEdgeIt;
alpar@400
   688
      friend class InEdgeIt;
alpar@400
   689
alpar@400
   690
    protected:
alpar@400
   691
      int n;
alpar@905
   692
      friend int NodeSet::id(Node v); 
alpar@400
   693
      Node(int nn) {n=nn;}
alpar@400
   694
    public:
alpar@400
   695
      Node() {}
alpar@400
   696
      Node (Invalid i) { n=-1; }
alpar@400
   697
      bool operator==(const Node i) const {return n==i.n;}
alpar@400
   698
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@400
   699
      bool operator<(const Node i) const {return n<i.n;}
alpar@400
   700
    };
alpar@400
   701
    
alpar@400
   702
    class NodeIt : public Node {
alpar@774
   703
      const NodeSet *G;
alpar@400
   704
      friend class NodeSet;
alpar@400
   705
    public:
alpar@579
   706
      NodeIt() : Node() { }
alpar@774
   707
      NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
alpar@579
   708
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   709
      NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
   710
      NodeIt &operator++() {
alpar@774
   711
	n=G->nodes[n].next; 
alpar@774
   712
	return *this; 
alpar@774
   713
      }
alpar@400
   714
    };
alpar@400
   715
alpar@400
   716
    class Edge {
alpar@400
   717
    public:
alpar@400
   718
      Edge() { }
alpar@400
   719
      Edge (Invalid) { }
alpar@400
   720
      bool operator==(const Edge i) const {return true;}
alpar@400
   721
      bool operator!=(const Edge i) const {return false;}
alpar@400
   722
      bool operator<(const Edge i) const {return false;}
alpar@400
   723
    };
alpar@400
   724
    
alpar@400
   725
    class EdgeIt : public Edge {
alpar@400
   726
    public:
alpar@400
   727
      EdgeIt(const NodeSet& G) : Edge() { }
alpar@774
   728
      EdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
   729
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
   730
      EdgeIt() : Edge() { }
alpar@774
   731
      EdgeIt operator++() { return INVALID; }
alpar@400
   732
    };
alpar@400
   733
    
alpar@400
   734
    class OutEdgeIt : public Edge {
alpar@400
   735
      friend class NodeSet;
alpar@400
   736
    public: 
alpar@400
   737
      OutEdgeIt() : Edge() { }
alpar@774
   738
      OutEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
   739
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@400
   740
      OutEdgeIt(const NodeSet& G,const Node v)	: Edge() {}
alpar@774
   741
      OutEdgeIt operator++() { return INVALID; }
alpar@400
   742
    };
alpar@400
   743
    
alpar@400
   744
    class InEdgeIt : public Edge {
alpar@400
   745
      friend class NodeSet;
alpar@400
   746
    public: 
alpar@400
   747
      InEdgeIt() : Edge() { }
alpar@774
   748
      InEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
   749
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@400
   750
      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
alpar@774
   751
      InEdgeIt operator++() { return INVALID; }
alpar@400
   752
    };
alpar@400
   753
alpar@400
   754
  };
alpar@400
   755
alpar@400
   756
alpar@400
   757
alpar@401
   758
  ///Graph structure using a node set of another graph.
alpar@401
   759
alpar@401
   760
  ///This structure can be used to establish another graph over a node set
alpar@401
   761
  /// of an existing one. The node iterator will go through the nodes of the
alpar@401
   762
  /// original graph, and the NodeMap's of both graphs will convert to
alpar@401
   763
  /// each other.
alpar@401
   764
  ///
alpar@404
   765
  ///\warning Adding or deleting nodes from the graph is not safe if an
alpar@404
   766
  ///\ref EdgeSet is currently attached to it!
alpar@404
   767
  ///
alpar@404
   768
  ///\todo Make it possible to add/delete edges from the base graph
alpar@404
   769
  ///(and from \ref EdgeSet, as well)
alpar@404
   770
  ///
alpar@401
   771
  ///\param GG The type of the graph which shares its node set with this class.
alpar@880
   772
  ///Its interface must conform to the
alpar@880
   773
  ///\ref skeleton::StaticGraph "StaticGraph" concept.
alpar@400
   774
  ///
alpar@880
   775
  ///It conforms to the 
alpar@880
   776
  ///\ref skeleton::ExtendableGraph "ExtendableGraph" concept.
alpar@880
   777
  ///\sa skeleton::ExtendableGraph.
alpar@880
   778
  ///\sa NodeSet.
alpar@400
   779
  template<typename GG>
alpar@400
   780
  class EdgeSet {
alpar@400
   781
alpar@400
   782
    typedef GG NodeGraphType;
alpar@400
   783
alpar@400
   784
    NodeGraphType &G;
alpar@400
   785
alpar@515
   786
  public:
deba@782
   787
alpar@400
   788
    class Node;
alpar@705
   789
    class Edge;
alpar@705
   790
    class OutEdgeIt;
alpar@705
   791
    class InEdgeIt;
alpar@705
   792
    class SymEdge;
deba@782
   793
deba@782
   794
    typedef EdgeSet Graph;
deba@782
   795
alpar@531
   796
    int id(Node v) const; 
alpar@531
   797
alpar@531
   798
    class Node : public NodeGraphType::Node {
alpar@531
   799
      friend class EdgeSet;
alpar@531
   800
      
alpar@531
   801
      friend class Edge;
alpar@531
   802
      friend class OutEdgeIt;
alpar@531
   803
      friend class InEdgeIt;
alpar@531
   804
      friend class SymEdge;
alpar@531
   805
alpar@531
   806
    public:
alpar@531
   807
      friend int EdgeSet::id(Node v) const; 
alpar@531
   808
    public:
alpar@531
   809
      Node() : NodeGraphType::Node() {}
alpar@531
   810
      Node (Invalid i) : NodeGraphType::Node(i) {}
alpar@531
   811
      Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
alpar@531
   812
    };
alpar@531
   813
    
alpar@531
   814
    class NodeIt : public NodeGraphType::NodeIt {
alpar@531
   815
      friend class EdgeSet;
alpar@531
   816
    public:
alpar@531
   817
      NodeIt() : NodeGraphType::NodeIt() { }
alpar@774
   818
      NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
alpar@531
   819
      NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
alpar@531
   820
      NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
alpar@531
   821
      NodeIt(const typename NodeGraphType::NodeIt &n)
alpar@531
   822
	: NodeGraphType::NodeIt(n) {}
alpar@579
   823
alpar@531
   824
      operator Node() { return Node(*this);}
alpar@774
   825
      NodeIt &operator++()
alpar@774
   826
      { this->NodeGraphType::NodeIt::operator++(); return *this;} 
alpar@531
   827
    };
alpar@515
   828
alpar@515
   829
  private:
alpar@400
   830
    //Edges are double linked.
alpar@400
   831
    //The free edges are only single linked using the "next_in" field.
alpar@400
   832
    struct NodeT 
alpar@400
   833
    {
alpar@400
   834
      int first_in,first_out;
alpar@400
   835
      NodeT() : first_in(-1), first_out(-1) { }
alpar@400
   836
    };
alpar@400
   837
alpar@400
   838
    struct EdgeT 
alpar@400
   839
    {
alpar@400
   840
      Node head, tail;
alpar@400
   841
      int prev_in, prev_out;
alpar@400
   842
      int next_in, next_out;
alpar@400
   843
    };
alpar@400
   844
alpar@400
   845
    
alpar@515
   846
    typename NodeGraphType::template NodeMap<NodeT> nodes;
alpar@400
   847
    
alpar@400
   848
    std::vector<EdgeT> edges;
alpar@400
   849
    //The first free edge
alpar@400
   850
    int first_free_edge;
alpar@400
   851
    
alpar@400
   852
  public:
alpar@400
   853
    
alpar@400
   854
    class Node;
alpar@400
   855
    class Edge;
alpar@400
   856
alpar@400
   857
    class NodeIt;
alpar@400
   858
    class EdgeIt;
alpar@400
   859
    class OutEdgeIt;
alpar@400
   860
    class InEdgeIt;
deba@782
   861
deba@782
   862
alpar@904
   863
    // Create edge map registry.
deba@782
   864
    CREATE_EDGE_MAP_REGISTRY;
alpar@904
   865
    // Create edge maps.
deba@897
   866
    CREATE_EDGE_MAP(ArrayMap);
deba@822
   867
alpar@904
   868
    // Import node maps from the NodeGraphType.
deba@822
   869
    IMPORT_NODE_MAP(NodeGraphType, graph.G, EdgeSet, graph);
alpar@400
   870
    
alpar@400
   871
    
alpar@400
   872
  public:
alpar@400
   873
alpar@408
   874
    ///Constructor
alpar@408
   875
    
alpar@408
   876
    ///Construates a new graph based on the nodeset of an existing one.
alpar@408
   877
    ///\param _G the base graph.
alpar@880
   878
    explicit EdgeSet(NodeGraphType &_G) 
deba@782
   879
      : G(_G), nodes(_G), edges(),
deba@782
   880
	first_free_edge(-1) {}
alpar@408
   881
    ///Copy constructor
alpar@408
   882
alpar@408
   883
    ///Makes a copy of an EdgeSet.
alpar@408
   884
    ///It will be based on the same graph.
alpar@880
   885
    explicit EdgeSet(const EdgeSet &_g) 
deba@782
   886
      : G(_g.G), nodes(_g.G), edges(_g.edges),
deba@782
   887
	first_free_edge(_g.first_free_edge) {}
alpar@400
   888
    
alpar@813
   889
    ///Number of nodes.
alpar@813
   890
    int nodeNum() const { return G.nodeNum(); }
alpar@813
   891
    ///Number of edges.
alpar@813
   892
    int edgeNum() const { return edges.size(); }
alpar@400
   893
alpar@813
   894
    /// Maximum node ID.
alpar@813
   895
    
alpar@813
   896
    /// Maximum node ID.
alpar@813
   897
    ///\sa id(Node)
alpar@813
   898
    int maxNodeId() const { return G.maxNodeId(); }
alpar@813
   899
    /// Maximum edge ID.
alpar@813
   900
    
alpar@813
   901
    /// Maximum edge ID.
alpar@813
   902
    ///\sa id(Edge)
alpar@813
   903
    int maxEdgeId() const { return edges.size()-1; }
alpar@400
   904
alpar@400
   905
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@400
   906
    Node head(Edge e) const { return edges[e.n].head; }
alpar@400
   907
alpar@400
   908
    NodeIt& first(NodeIt& v) const { 
alpar@400
   909
      v=NodeIt(*this); return v; }
alpar@400
   910
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   911
      e=EdgeIt(*this); return e; }
alpar@400
   912
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   913
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   914
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   915
      e=InEdgeIt(*this,v); return e; }
alpar@400
   916
alpar@813
   917
    /// Node ID.
alpar@813
   918
    
alpar@813
   919
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   920
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   921
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   922
    ///
alpar@813
   923
    /// The ID of the \ref INVALID node is -1.
alpar@813
   924
    ///\return The ID of the node \c v. 
alpar@813
   925
    int id(Node v) { return G.id(v); }
alpar@813
   926
    /// Edge ID.
alpar@813
   927
    
alpar@813
   928
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   929
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   930
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   931
    ///
alpar@813
   932
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   933
    ///\return The ID of the edge \c e. 
alpar@905
   934
    static int id(Edge e) { return e.n; }
alpar@400
   935
alpar@400
   936
    /// Adds a new node to the graph.
alpar@579
   937
    Node addNode() { return G.addNode(); }
alpar@400
   938
    
alpar@400
   939
    Edge addEdge(Node u, Node v) {
alpar@400
   940
      int n;
alpar@400
   941
      
alpar@400
   942
      if(first_free_edge==-1)
alpar@400
   943
	{
alpar@400
   944
	  n = edges.size();
alpar@400
   945
	  edges.push_back(EdgeT());
alpar@400
   946
	}
alpar@400
   947
      else {
alpar@400
   948
	n = first_free_edge;
alpar@400
   949
	first_free_edge = edges[n].next_in;
alpar@400
   950
      }
alpar@400
   951
      
alpar@401
   952
      edges[n].tail = u; edges[n].head = v;
alpar@400
   953
alpar@401
   954
      edges[n].next_out = nodes[u].first_out;
alpar@401
   955
      if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
alpar@401
   956
      edges[n].next_in = nodes[v].first_in;
alpar@401
   957
      if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
alpar@400
   958
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@400
   959
	
alpar@401
   960
      nodes[u].first_out = nodes[v].first_in = n;
alpar@400
   961
alpar@400
   962
      Edge e; e.n=n;
alpar@400
   963
alpar@400
   964
      //Update dynamic maps
deba@782
   965
      edge_maps.add(e);
alpar@400
   966
alpar@400
   967
      return e;
alpar@400
   968
    }
alpar@400
   969
alpar@774
   970
    /// Finds an edge between two nodes.
alpar@774
   971
alpar@774
   972
    /// Finds an edge from node \c u to node \c v.
alpar@774
   973
    ///
alpar@774
   974
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
   975
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
   976
    /// the next edge from \c u to \c v after \c prev.
alpar@774
   977
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
   978
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   979
    {
alpar@774
   980
      int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
alpar@774
   981
      while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
alpar@774
   982
      prev.n=e;
alpar@774
   983
      return prev;
alpar@774
   984
    }
alpar@774
   985
    
alpar@400
   986
  private:
alpar@400
   987
    void eraseEdge(int n) {
alpar@400
   988
      
alpar@400
   989
      if(edges[n].next_in!=-1)
alpar@400
   990
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@400
   991
      if(edges[n].prev_in!=-1)
alpar@400
   992
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@400
   993
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@400
   994
      
alpar@400
   995
      if(edges[n].next_out!=-1)
alpar@400
   996
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@400
   997
      if(edges[n].prev_out!=-1)
alpar@400
   998
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@400
   999
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@400
  1000
      
alpar@400
  1001
      edges[n].next_in = first_free_edge;
alpar@400
  1002
      first_free_edge = -1;      
alpar@400
  1003
alpar@400
  1004
      //Update dynamic maps
deba@782
  1005
      Edge e; e.n = n;
deba@782
  1006
      edge_maps.erase(e);
alpar@400
  1007
    }
alpar@400
  1008
      
alpar@400
  1009
  public:
alpar@400
  1010
alpar@400
  1011
    void erase(Edge e) { eraseEdge(e.n); }
alpar@400
  1012
alpar@579
  1013
    ///Clear all edges. (Doesn't clear the nodes!)
alpar@579
  1014
    void clear() {
deba@782
  1015
      edge_maps.clear();
alpar@579
  1016
      edges.clear();
alpar@579
  1017
      first_free_edge=-1;
alpar@579
  1018
    }
alpar@579
  1019
alpar@579
  1020
alpar@400
  1021
    class Edge {
alpar@579
  1022
    public:
alpar@400
  1023
      friend class EdgeSet;
alpar@400
  1024
      template <typename T> friend class EdgeMap;
alpar@400
  1025
alpar@400
  1026
      friend class Node;
alpar@400
  1027
      friend class NodeIt;
alpar@905
  1028
    protected:
alpar@579
  1029
      int n;
alpar@400
  1030
      friend int EdgeSet::id(Edge e) const;
alpar@400
  1031
alpar@400
  1032
      Edge(int nn) {n=nn;}
alpar@400
  1033
    public:
alpar@400
  1034
      Edge() { }
alpar@400
  1035
      Edge (Invalid) { n=-1; }
alpar@400
  1036
      bool operator==(const Edge i) const {return n==i.n;}
alpar@400
  1037
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@400
  1038
      bool operator<(const Edge i) const {return n<i.n;}
alpar@400
  1039
    };
alpar@400
  1040
    
alpar@400
  1041
    class EdgeIt : public Edge {
alpar@400
  1042
      friend class EdgeSet;
alpar@579
  1043
      template <typename T> friend class EdgeMap;
alpar@579
  1044
    
alpar@774
  1045
      const EdgeSet *G;
alpar@400
  1046
    public:
alpar@774
  1047
      EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
alpar@503
  1048
        NodeIt m;
alpar@774
  1049
	for(G->first(m);
alpar@774
  1050
	    m!=INVALID && G->nodes[m].first_in == -1;  ++m);
alpar@774
  1051
	///\bug AJJAJ! This is a non sense!!!!!!!
alpar@774
  1052
	this->n = m!=INVALID?-1:G->nodes[m].first_in;
alpar@400
  1053
      }
alpar@774
  1054
      EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1055
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1056
      EdgeIt() : Edge() { }
alpar@774
  1057
      ///.
alpar@774
  1058
      
alpar@774
  1059
      ///\bug UNIMPLEMENTED!!!!!
alpar@774
  1060
      //
alpar@774
  1061
      EdgeIt &operator++() {
alpar@774
  1062
	return *this;
alpar@774
  1063
      }
alpar@400
  1064
    };
alpar@400
  1065
    
alpar@400
  1066
    class OutEdgeIt : public Edge {
alpar@774
  1067
      const EdgeSet *G;
alpar@400
  1068
      friend class EdgeSet;
alpar@400
  1069
    public: 
alpar@400
  1070
      OutEdgeIt() : Edge() { }
alpar@400
  1071
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1072
      OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1073
alpar@774
  1074
      OutEdgeIt(const EdgeSet& _G,const Node v) :
alpar@774
  1075
	Edge(_G.nodes[v].first_out), G(&_G) { }
deba@844
  1076
      OutEdgeIt &operator++() { 
deba@844
  1077
	Edge::n = G->edges[Edge::n].next_out;
deba@844
  1078
	return *this; 
deba@844
  1079
      }
alpar@400
  1080
    };
alpar@400
  1081
    
alpar@400
  1082
    class InEdgeIt : public Edge {
alpar@774
  1083
      const EdgeSet *G;
alpar@400
  1084
      friend class EdgeSet;
alpar@400
  1085
    public: 
alpar@400
  1086
      InEdgeIt() : Edge() { }
alpar@400
  1087
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1088
      InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@774
  1089
      InEdgeIt(const EdgeSet& _G,Node v)
alpar@774
  1090
	: Edge(_G.nodes[v].first_in), G(&_G) { }
deba@844
  1091
      InEdgeIt &operator++() { 
deba@844
  1092
	Edge::n = G->edges[Edge::n].next_in; 
deba@844
  1093
	return *this; 
deba@844
  1094
      }
alpar@400
  1095
    };
deba@782
  1096
    
alpar@400
  1097
  };
alpar@406
  1098
alpar@579
  1099
  template<typename GG>
alpar@579
  1100
  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
alpar@531
  1101
alpar@406
  1102
/// @}  
alpar@406
  1103
alpar@395
  1104
} //namespace hugo
alpar@395
  1105
alpar@405
  1106
#endif //HUGO_LIST_GRAPH_H