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