src/lemon/list_graph.h
author ladanyi
Mon, 11 Oct 2004 18:02:48 +0000
changeset 942 75fdd0c6866d
parent 921 818510fa3d99
child 946 c94ef40a22ce
permissions -rw-r--r--
Naming and coding style fixes and various other changes.
alpar@906
     1
/* -*- C++ -*-
alpar@921
     2
 * src/lemon/list_graph.h - Part of LEMON, 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@921
    17
#ifndef LEMON_LIST_GRAPH_H
alpar@921
    18
#define LEMON_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
alpar@921
    27
#include <lemon/invalid.h>
alpar@395
    28
alpar@921
    29
#include <lemon/map_registry.h>
alpar@921
    30
#include <lemon/array_map.h>
deba@782
    31
alpar@921
    32
#include <lemon/map_defines.h>
deba@782
    33
deba@782
    34
alpar@921
    35
namespace lemon {
alpar@395
    36
alpar@406
    37
/// \addtogroup graphs
alpar@406
    38
/// @{
alpar@406
    39
alpar@401
    40
  ///A list graph class.
alpar@395
    41
alpar@397
    42
  ///This is a simple and fast erasable graph implementation.
alpar@397
    43
  ///
alpar@880
    44
  ///It conforms to the
alpar@880
    45
  ///\ref skeleton::ErasableGraph "ErasableGraph" concept.
alpar@880
    46
  ///\sa skeleton::ErasableGraph.
alpar@397
    47
  class ListGraph {
alpar@395
    48
alpar@397
    49
    //Nodes are double linked.
alpar@397
    50
    //The free nodes are only single linked using the "next" field.
alpar@395
    51
    struct NodeT 
alpar@395
    52
    {
alpar@397
    53
      int first_in,first_out;
alpar@397
    54
      int prev, next;
alpar@395
    55
    };
alpar@397
    56
    //Edges are double linked.
alpar@397
    57
    //The free edges are only single linked using the "next_in" field.
alpar@395
    58
    struct EdgeT 
alpar@395
    59
    {
alpar@397
    60
      int head, tail;
alpar@397
    61
      int prev_in, prev_out;
alpar@397
    62
      int next_in, next_out;
alpar@395
    63
    };
alpar@395
    64
alpar@395
    65
    std::vector<NodeT> nodes;
alpar@397
    66
    //The first node
alpar@397
    67
    int first_node;
alpar@397
    68
    //The first free node
alpar@397
    69
    int first_free_node;
alpar@395
    70
    std::vector<EdgeT> edges;
alpar@397
    71
    //The first free edge
alpar@397
    72
    int first_free_edge;
alpar@395
    73
    
deba@782
    74
  public:
alpar@395
    75
    
deba@782
    76
    typedef ListGraph Graph;
alpar@397
    77
    
alpar@395
    78
    class Node;
alpar@395
    79
    class Edge;
alpar@395
    80
alpar@395
    81
    
alpar@395
    82
  public:
alpar@395
    83
alpar@395
    84
    class NodeIt;
alpar@395
    85
    class EdgeIt;
alpar@395
    86
    class OutEdgeIt;
alpar@395
    87
    class InEdgeIt;
deba@782
    88
alpar@904
    89
    // Create map registries.
deba@782
    90
    CREATE_MAP_REGISTRIES;
alpar@905
    91
    // Create node and edge maps.
deba@897
    92
    CREATE_MAPS(ArrayMap);
deba@782
    93
alpar@395
    94
  public:
alpar@395
    95
deba@782
    96
    ListGraph() 
deba@782
    97
      : nodes(), first_node(-1),
deba@782
    98
	first_free_node(-1), edges(), first_free_edge(-1) {}
deba@782
    99
deba@782
   100
    ListGraph(const ListGraph &_g) 
deba@782
   101
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   102
	first_free_node(_g.first_free_node), edges(_g.edges),
deba@782
   103
	first_free_edge(_g.first_free_edge) {}
alpar@395
   104
    
deba@937
   105
    /// \bug In the vector can be hole if a node is erased from the graph.
alpar@813
   106
    ///Number of nodes.
alpar@813
   107
    int nodeNum() const { return nodes.size(); }
alpar@813
   108
    ///Number of edges.
alpar@813
   109
    int edgeNum() const { return edges.size(); }
alpar@395
   110
alpar@813
   111
    ///Set the expected maximum number of edges.
alpar@695
   112
alpar@695
   113
    ///With this function, it is possible to set the expected number of edges.
alpar@695
   114
    ///The use of this fasten the building of the graph and makes
alpar@695
   115
    ///it possible to avoid the superfluous memory allocation.
alpar@695
   116
    void reserveEdge(int n) { edges.reserve(n); };
alpar@695
   117
    
alpar@813
   118
    /// Maximum node ID.
alpar@813
   119
    
alpar@813
   120
    /// Maximum node ID.
alpar@813
   121
    ///\sa id(Node)
alpar@813
   122
    int maxNodeId() const { return nodes.size()-1; } 
alpar@813
   123
    /// Maximum edge ID.
alpar@813
   124
    
alpar@813
   125
    /// Maximum edge ID.
alpar@813
   126
    ///\sa id(Edge)
alpar@813
   127
    int maxEdgeId() const { return edges.size()-1; }
alpar@395
   128
alpar@395
   129
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@395
   130
    Node head(Edge e) const { return edges[e.n].head; }
alpar@395
   131
alpar@713
   132
    NodeIt& first(NodeIt& v) const { 
alpar@395
   133
      v=NodeIt(*this); return v; }
alpar@713
   134
    EdgeIt& first(EdgeIt& e) const { 
alpar@395
   135
      e=EdgeIt(*this); return e; }
alpar@713
   136
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@395
   137
      e=OutEdgeIt(*this,v); return e; }
alpar@713
   138
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@395
   139
      e=InEdgeIt(*this,v); return e; }
alpar@395
   140
alpar@813
   141
    /// Node ID.
alpar@813
   142
    
alpar@813
   143
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   144
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   145
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   146
    ///
alpar@813
   147
    /// The ID of the \ref INVALID node is -1.
alpar@813
   148
    ///\return The ID of the node \c v. 
alpar@713
   149
    static int id(Node v) { return v.n; }
alpar@813
   150
    /// Edge ID.
alpar@813
   151
    
alpar@813
   152
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   153
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   154
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   155
    ///
alpar@813
   156
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   157
    ///\return The ID of the edge \c e. 
alpar@713
   158
    static int id(Edge e) { return e.n; }
alpar@395
   159
alpar@397
   160
    /// Adds a new node to the graph.
alpar@397
   161
alpar@813
   162
    /// \warning It adds the new node to the front of the list.
alpar@397
   163
    /// (i.e. the lastly added node becomes the first.)
alpar@395
   164
    Node addNode() {
alpar@397
   165
      int n;
alpar@397
   166
      
alpar@397
   167
      if(first_free_node==-1)
alpar@397
   168
	{
alpar@397
   169
	  n = nodes.size();
alpar@397
   170
	  nodes.push_back(NodeT());
alpar@397
   171
	}
alpar@397
   172
      else {
alpar@397
   173
	n = first_free_node;
alpar@397
   174
	first_free_node = nodes[n].next;
alpar@397
   175
      }
alpar@397
   176
      
alpar@397
   177
      nodes[n].next = first_node;
alpar@397
   178
      if(first_node != -1) nodes[first_node].prev = n;
alpar@397
   179
      first_node = n;
alpar@397
   180
      nodes[n].prev = -1;
alpar@397
   181
      
alpar@397
   182
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@397
   183
      
alpar@397
   184
      Node nn; nn.n=n;
alpar@395
   185
alpar@397
   186
      //Update dynamic maps
deba@782
   187
      node_maps.add(nn);
alpar@395
   188
alpar@397
   189
      return nn;
alpar@395
   190
    }
alpar@395
   191
    
alpar@395
   192
    Edge addEdge(Node u, Node v) {
alpar@397
   193
      int n;
alpar@397
   194
      
alpar@397
   195
      if(first_free_edge==-1)
alpar@397
   196
	{
alpar@397
   197
	  n = edges.size();
alpar@397
   198
	  edges.push_back(EdgeT());
alpar@397
   199
	}
alpar@397
   200
      else {
alpar@397
   201
	n = first_free_edge;
alpar@397
   202
	first_free_edge = edges[n].next_in;
alpar@397
   203
      }
alpar@397
   204
      
alpar@397
   205
      edges[n].tail = u.n; edges[n].head = v.n;
alpar@395
   206
alpar@397
   207
      edges[n].next_out = nodes[u.n].first_out;
alpar@397
   208
      if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
alpar@397
   209
      edges[n].next_in = nodes[v.n].first_in;
alpar@397
   210
      if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
alpar@397
   211
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@397
   212
	
alpar@397
   213
      nodes[u.n].first_out = nodes[v.n].first_in = n;
alpar@397
   214
alpar@397
   215
      Edge e; e.n=n;
alpar@397
   216
alpar@397
   217
      //Update dynamic maps
deba@782
   218
      edge_maps.add(e);
alpar@395
   219
alpar@395
   220
      return e;
alpar@395
   221
    }
alpar@774
   222
    
alpar@774
   223
    /// Finds an edge between two nodes.
alpar@395
   224
alpar@774
   225
    /// Finds an edge from node \c u to node \c v.
alpar@774
   226
    ///
alpar@774
   227
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
   228
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
   229
    /// the next edge from \c u to \c v after \c prev.
alpar@774
   230
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
   231
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   232
    {
alpar@774
   233
      int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
alpar@774
   234
      while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
alpar@774
   235
      prev.n=e;
alpar@774
   236
      return prev;
alpar@774
   237
    }
alpar@774
   238
    
alpar@397
   239
  private:
alpar@397
   240
    void eraseEdge(int n) {
alpar@397
   241
      
alpar@397
   242
      if(edges[n].next_in!=-1)
alpar@397
   243
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@397
   244
      if(edges[n].prev_in!=-1)
alpar@397
   245
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@397
   246
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@397
   247
      
alpar@397
   248
      if(edges[n].next_out!=-1)
alpar@397
   249
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@397
   250
      if(edges[n].prev_out!=-1)
alpar@397
   251
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@397
   252
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@397
   253
      
alpar@397
   254
      edges[n].next_in = first_free_edge;
alpar@695
   255
      first_free_edge = n;      
alpar@397
   256
alpar@397
   257
      //Update dynamic maps
alpar@397
   258
      Edge e; e.n=n;
deba@782
   259
      edge_maps.erase(e);
deba@782
   260
alpar@397
   261
    }
alpar@397
   262
      
alpar@397
   263
  public:
alpar@397
   264
alpar@397
   265
    void erase(Node nn) {
alpar@397
   266
      int n=nn.n;
alpar@397
   267
      
alpar@397
   268
      int m;
alpar@397
   269
      while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@397
   270
      while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@397
   271
alpar@397
   272
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@397
   273
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@397
   274
      else first_node = nodes[n].next;
alpar@397
   275
      
alpar@397
   276
      nodes[n].next = first_free_node;
alpar@397
   277
      first_free_node = n;
alpar@397
   278
alpar@397
   279
      //Update dynamic maps
deba@782
   280
      node_maps.erase(nn);
deba@782
   281
alpar@397
   282
    }
alpar@397
   283
    
alpar@397
   284
    void erase(Edge e) { eraseEdge(e.n); }
alpar@397
   285
alpar@397
   286
    void clear() {
deba@782
   287
      edge_maps.clear();
deba@782
   288
      edges.clear();
deba@782
   289
      node_maps.clear();
deba@782
   290
      nodes.clear();
alpar@397
   291
      first_node=first_free_node=first_free_edge=-1;
alpar@397
   292
    }
alpar@395
   293
alpar@395
   294
    class Node {
alpar@397
   295
      friend class ListGraph;
alpar@395
   296
      template <typename T> friend class NodeMap;
alpar@400
   297
       
alpar@395
   298
      friend class Edge;
alpar@395
   299
      friend class OutEdgeIt;
alpar@395
   300
      friend class InEdgeIt;
alpar@395
   301
      friend class SymEdge;
alpar@395
   302
alpar@395
   303
    protected:
alpar@395
   304
      int n;
alpar@722
   305
      friend int ListGraph::id(Node v); 
alpar@395
   306
      Node(int nn) {n=nn;}
alpar@395
   307
    public:
alpar@395
   308
      Node() {}
alpar@503
   309
      Node (Invalid) { n=-1; }
alpar@395
   310
      bool operator==(const Node i) const {return n==i.n;}
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@774
   313
      //      ///Validity check
alpar@774
   314
      //      operator bool() { return n!=-1; }
alpar@395
   315
    };
alpar@395
   316
    
alpar@395
   317
    class NodeIt : public Node {
alpar@774
   318
      const ListGraph *G;
alpar@397
   319
      friend class ListGraph;
alpar@395
   320
    public:
alpar@400
   321
      NodeIt() : Node() { }
alpar@400
   322
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   323
      NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
   324
      NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
alpar@774
   325
      NodeIt &operator++() {
alpar@774
   326
	n=G->nodes[n].next; 
alpar@774
   327
	return *this; 
alpar@774
   328
      }
alpar@774
   329
      //      ///Validity check
alpar@774
   330
      //      operator bool() { return Node::operator bool(); }      
alpar@395
   331
    };
alpar@395
   332
alpar@395
   333
    class Edge {
alpar@397
   334
      friend class ListGraph;
alpar@395
   335
      template <typename T> friend class EdgeMap;
alpar@395
   336
alpar@905
   337
      friend class SymListGraph;
alpar@395
   338
      
alpar@395
   339
      friend class Node;
alpar@395
   340
      friend class NodeIt;
alpar@395
   341
    protected:
alpar@395
   342
      int n;
alpar@722
   343
      friend int ListGraph::id(Edge e);
alpar@395
   344
alpar@706
   345
    public:
alpar@706
   346
      /// An Edge with id \c n.
alpar@706
   347
alpar@706
   348
      /// \bug It should be
alpar@706
   349
      /// obtained by a member function of the Graph.
alpar@395
   350
      Edge(int nn) {n=nn;}
alpar@706
   351
alpar@395
   352
      Edge() { }
alpar@395
   353
      Edge (Invalid) { n=-1; }
alpar@395
   354
      bool operator==(const Edge i) const {return n==i.n;}
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@774
   357
      //      ///Validity check
alpar@774
   358
      //      operator bool() { return n!=-1; }
alpar@774
   359
   };
alpar@395
   360
    
alpar@395
   361
    class EdgeIt : public Edge {
alpar@774
   362
      const ListGraph *G;
alpar@397
   363
      friend class ListGraph;
alpar@395
   364
    public:
alpar@774
   365
      EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
alpar@397
   366
      	int m;
alpar@774
   367
	for(m=_G.first_node;
alpar@774
   368
	    m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
alpar@774
   369
	n = (m==-1)?-1:_G.nodes[m].first_in;
alpar@397
   370
      }
alpar@395
   371
      EdgeIt (Invalid i) : Edge(i) { }
alpar@774
   372
      EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   373
      EdgeIt() : Edge() { }
alpar@774
   374
      EdgeIt &operator++() {
alpar@774
   375
	if(G->edges[n].next_in!=-1) n=G->edges[n].next_in;
alpar@774
   376
	else {
alpar@774
   377
	  int nn;
alpar@774
   378
	  for(nn=G->nodes[G->edges[n].head].next;
alpar@774
   379
	      nn!=-1 && G->nodes[nn].first_in == -1;
alpar@774
   380
	      nn = G->nodes[nn].next) ;
alpar@774
   381
	  n = (nn==-1)?-1:G->nodes[nn].first_in;
alpar@774
   382
	}
alpar@774
   383
	return *this;
alpar@774
   384
      }
alpar@774
   385
      //      ///Validity check
alpar@774
   386
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   387
    };
alpar@395
   388
    
alpar@395
   389
    class OutEdgeIt : public Edge {
alpar@774
   390
      const ListGraph *G;
alpar@397
   391
      friend class ListGraph;
alpar@395
   392
    public: 
alpar@395
   393
      OutEdgeIt() : Edge() { }
alpar@774
   394
      OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   395
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@395
   396
alpar@774
   397
      OutEdgeIt(const ListGraph& _G,const Node v)
alpar@774
   398
	: Edge(_G.nodes[v.n].first_out), G(&_G) {}
alpar@774
   399
      OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; }
alpar@774
   400
      //      ///Validity check
alpar@774
   401
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   402
    };
alpar@395
   403
    
alpar@395
   404
    class InEdgeIt : public Edge {
alpar@774
   405
      const ListGraph *G;
alpar@397
   406
      friend class ListGraph;
alpar@395
   407
    public: 
alpar@395
   408
      InEdgeIt() : Edge() { }
alpar@774
   409
      InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   410
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
   411
      InEdgeIt(const ListGraph& _G,Node v)
alpar@774
   412
	: Edge(_G.nodes[v.n].first_in), G(&_G) { }
alpar@774
   413
      InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
alpar@774
   414
      //      ///Validity check
alpar@774
   415
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   416
    };
alpar@395
   417
  };
alpar@395
   418
alpar@395
   419
  ///Graph for bidirectional edges.
alpar@395
   420
alpar@395
   421
  ///The purpose of this graph structure is to handle graphs
alpar@395
   422
  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
alpar@395
   423
  ///of oppositely directed edges.
alpar@395
   424
  ///There is a new edge map type called
alpar@921
   425
  ///\ref lemon::SymListGraph::SymEdgeMap "SymEdgeMap"
alpar@395
   426
  ///that complements this
alpar@395
   427
  ///feature by
alpar@395
   428
  ///storing shared values for the edge pairs. The usual
alpar@921
   429
  ///\ref lemon::skeleton::StaticGraph::EdgeMap "EdgeMap"
alpar@395
   430
  ///can be used
alpar@395
   431
  ///as well.
alpar@395
   432
  ///
alpar@395
   433
  ///The oppositely directed edge can also be obtained easily
alpar@921
   434
  ///using \ref lemon::SymListGraph::opposite() "opposite()" member function.
alpar@397
   435
  ///
alpar@397
   436
  ///Here erase(Edge) deletes a pair of edges.
alpar@397
   437
  ///
alpar@397
   438
  ///\todo this date structure need some reconsiderations. Maybe it
alpar@397
   439
  ///should be implemented independently from ListGraph.
deba@937
   440
  /*  
alpar@397
   441
  class SymListGraph : public ListGraph
alpar@395
   442
  {
alpar@395
   443
  public:
deba@782
   444
deba@782
   445
    typedef SymListGraph Graph;
deba@782
   446
alpar@904
   447
    // Create symmetric map registry.
deba@782
   448
    CREATE_SYM_EDGE_MAP_REGISTRY;
alpar@904
   449
    // Create symmetric edge map.
deba@897
   450
    CREATE_SYM_EDGE_MAP(ArrayMap);
alpar@395
   451
alpar@397
   452
    SymListGraph() : ListGraph() { }
alpar@397
   453
    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
alpar@397
   454
    ///Adds a pair of oppositely directed edges to the graph.
alpar@395
   455
    Edge addEdge(Node u, Node v)
alpar@395
   456
    {
alpar@397
   457
      Edge e = ListGraph::addEdge(u,v);
deba@782
   458
      Edge f = ListGraph::addEdge(v,u);
deba@782
   459
      sym_edge_maps.add(e);
deba@782
   460
      sym_edge_maps.add(f);
deba@782
   461
      
alpar@395
   462
      return e;
alpar@395
   463
    }
alpar@395
   464
deba@782
   465
    void erase(Node n) { ListGraph::erase(n);}
alpar@395
   466
    ///The oppositely directed edge.
alpar@395
   467
alpar@395
   468
    ///Returns the oppositely directed
alpar@395
   469
    ///pair of the edge \c e.
alpar@713
   470
    static Edge opposite(Edge e)
alpar@395
   471
    {
alpar@395
   472
      Edge f;
alpar@905
   473
      f.n = e.n - 2*(e.n%2) + 1;
alpar@395
   474
      return f;
alpar@395
   475
    }
alpar@395
   476
    
alpar@397
   477
    ///Removes a pair of oppositely directed edges to the graph.
alpar@397
   478
    void erase(Edge e) {
deba@782
   479
      Edge f = opposite(e);
deba@782
   480
      sym_edge_maps.erase(e);
deba@782
   481
      sym_edge_maps.erase(f);
deba@782
   482
      ListGraph::erase(f);
alpar@397
   483
      ListGraph::erase(e);
deba@782
   484
    }    
deba@937
   485
    };*/
deba@937
   486
deba@937
   487
  class SymListGraph : public ListGraph {
deba@937
   488
    typedef ListGraph Parent;
deba@937
   489
  public:
deba@937
   490
deba@937
   491
    typedef SymListGraph Graph;
deba@937
   492
deba@937
   493
    typedef ListGraph::Node Node;
deba@937
   494
    typedef ListGraph::NodeIt NodeIt;
deba@937
   495
deba@937
   496
    class SymEdge;
deba@937
   497
    class SymEdgeIt;
deba@937
   498
deba@937
   499
    class Edge;
deba@937
   500
    class EdgeIt;
deba@937
   501
    class OutEdgeIt;
deba@937
   502
    class InEdgeIt;
deba@937
   503
deba@937
   504
    template <typename Value>
deba@937
   505
    class NodeMap : public Parent::NodeMap<Value> {      
deba@937
   506
    public:
deba@937
   507
      NodeMap(const SymListGraph& g) 
deba@937
   508
	: SymListGraph::Parent::NodeMap<Value>(g) {}
deba@937
   509
      NodeMap(const SymListGraph& g, Value v) 
deba@937
   510
	: SymListGraph::Parent::NodeMap<Value>(g, v) {}
deba@937
   511
      template<typename TT> 
deba@937
   512
      NodeMap(const NodeMap<TT>& copy) 
deba@937
   513
	: SymListGraph::Parent::NodeMap<Value>(copy) { }            
deba@937
   514
    };
deba@937
   515
deba@937
   516
    template <typename Value>
deba@937
   517
    class SymEdgeMap : public Parent::EdgeMap<Value> {
deba@937
   518
    public:
deba@937
   519
      typedef SymEdge KeyType;
deba@937
   520
deba@937
   521
      SymEdgeMap(const SymListGraph& g) 
deba@937
   522
	: SymListGraph::Parent::EdgeMap<Value>(g) {}
deba@937
   523
      SymEdgeMap(const SymListGraph& g, Value v) 
deba@937
   524
	: SymListGraph::Parent::EdgeMap<Value>(g, v) {}
deba@937
   525
      template<typename TT> 
deba@937
   526
      SymEdgeMap(const SymEdgeMap<TT>& copy) 
deba@937
   527
	: SymListGraph::Parent::EdgeMap<Value>(copy) { }
deba@937
   528
      
deba@937
   529
    };
deba@937
   530
deba@937
   531
    // Create edge map registry.
deba@937
   532
    CREATE_EDGE_MAP_REGISTRY;
deba@937
   533
    // Create edge maps.
deba@937
   534
    CREATE_EDGE_MAP(ArrayMap);
deba@937
   535
deba@937
   536
    class Edge {
deba@937
   537
      friend class SymListGraph;
deba@937
   538
      friend class SymListGraph::EdgeIt;
deba@937
   539
      friend class SymListGraph::OutEdgeIt;
deba@937
   540
      friend class SymListGraph::InEdgeIt;
deba@937
   541
      
deba@937
   542
    protected:
deba@937
   543
      int id;
deba@937
   544
deba@937
   545
      Edge(int pid) { id = pid; }
deba@937
   546
deba@937
   547
    public:
deba@937
   548
      /// An Edge with id \c n.
deba@937
   549
deba@937
   550
      Edge() { }
deba@937
   551
      Edge (Invalid) { id = -1; }
deba@937
   552
deba@937
   553
      operator SymEdge(){ return SymEdge(id >> 1);}
deba@937
   554
      
deba@937
   555
      bool operator==(const Edge i) const {return id == i.id;}
deba@937
   556
      bool operator!=(const Edge i) const {return id != i.id;}
deba@937
   557
      bool operator<(const Edge i) const {return id < i.id;}
deba@937
   558
      //      ///Validity check
deba@937
   559
      //      operator bool() { return n!=-1; }
deba@937
   560
    };
deba@937
   561
deba@937
   562
    class SymEdge : public ListGraph::Edge {
deba@937
   563
      friend class SymListGraph;
deba@937
   564
      friend class SymListGraph::Edge;
deba@937
   565
      typedef ListGraph::Edge Parent;
deba@937
   566
deba@937
   567
    protected:      
deba@937
   568
      SymEdge(int pid) : Parent(pid) {}
deba@937
   569
    public:
deba@937
   570
deba@937
   571
      SymEdge() { }
deba@937
   572
      SymEdge(const ListGraph::Edge& i) : Parent(i) {} 
deba@937
   573
      SymEdge (Invalid) : Parent(INVALID) {}
deba@937
   574
deba@937
   575
    };
deba@937
   576
deba@937
   577
    class OutEdgeIt {
deba@937
   578
      Parent::OutEdgeIt out;
deba@937
   579
      Parent::InEdgeIt in;      
deba@937
   580
    public: 
deba@937
   581
      OutEdgeIt() {}
deba@937
   582
      OutEdgeIt(const SymListGraph& g, Edge e) { 
deba@937
   583
	if ((e.id & 1) == 0) {	
deba@937
   584
	  out = Parent::OutEdgeIt(g, SymEdge(e));
deba@937
   585
	  in = Parent::InEdgeIt(g, g.tail(e));
deba@937
   586
	} else {
deba@937
   587
	  out = Parent::OutEdgeIt(INVALID);
deba@937
   588
	  in = Parent::InEdgeIt(g, SymEdge(e));
deba@937
   589
	}
deba@937
   590
      }
deba@937
   591
      OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
deba@937
   592
deba@937
   593
      OutEdgeIt(const SymListGraph& g, const Node v)
deba@937
   594
	: out(g, v), in(g, v) {}
deba@937
   595
      OutEdgeIt &operator++() { 
deba@937
   596
	if (out != INVALID) {
deba@937
   597
	  ++out;
deba@937
   598
	} else {
deba@937
   599
	  ++in;
deba@937
   600
	}
deba@937
   601
	return *this; 
deba@937
   602
      }
deba@937
   603
deba@937
   604
      operator Edge() const {
deba@937
   605
	if (out == INVALID && in == INVALID) return INVALID;
deba@937
   606
	return out != INVALID ? forward(out) : backward(in);
deba@937
   607
      }
deba@937
   608
deba@937
   609
      bool operator==(const Edge i) const {return Edge(*this) == i;}
deba@937
   610
      bool operator!=(const Edge i) const {return Edge(*this) != i;}
deba@937
   611
      bool operator<(const Edge i) const {return Edge(*this) < i;}
deba@937
   612
    };
deba@937
   613
deba@937
   614
    class InEdgeIt {
deba@937
   615
      Parent::OutEdgeIt out;
deba@937
   616
      Parent::InEdgeIt in;      
deba@937
   617
    public: 
deba@937
   618
      InEdgeIt() {}
deba@937
   619
      InEdgeIt(const SymListGraph& g, Edge e) { 
deba@937
   620
	if ((e.id & 1) == 0) {	
deba@937
   621
	  out = Parent::OutEdgeIt(g, SymEdge(e));
deba@937
   622
	  in = Parent::InEdgeIt(g, g.tail(e));
deba@937
   623
	} else {
deba@937
   624
	  out = Parent::OutEdgeIt(INVALID);
deba@937
   625
	  in = Parent::InEdgeIt(g, SymEdge(e));
deba@937
   626
	}
deba@937
   627
      }
deba@937
   628
      InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
deba@937
   629
deba@937
   630
      InEdgeIt(const SymListGraph& g, const Node v)
deba@937
   631
	: out(g, v), in(g, v) {}
deba@937
   632
deba@937
   633
      InEdgeIt &operator++() { 
deba@937
   634
	if (out != INVALID) {
deba@937
   635
	  ++out;
deba@937
   636
	} else {
deba@937
   637
	  ++in;
deba@937
   638
	}
deba@937
   639
	return *this; 
deba@937
   640
      }
deba@937
   641
deba@937
   642
      operator Edge() const {
deba@937
   643
	if (out == INVALID && in == INVALID) return INVALID;
deba@937
   644
	return out != INVALID ? backward(out) : forward(in);
deba@937
   645
      }
deba@937
   646
deba@937
   647
      bool operator==(const Edge i) const {return Edge(*this) == i;}
deba@937
   648
      bool operator!=(const Edge i) const {return Edge(*this) != i;}
deba@937
   649
      bool operator<(const Edge i) const {return Edge(*this) < i;}
deba@937
   650
    };
deba@937
   651
deba@937
   652
    class SymEdgeIt : public Parent::EdgeIt {
deba@937
   653
deba@937
   654
    public:
deba@937
   655
      SymEdgeIt() {}
deba@937
   656
deba@937
   657
      SymEdgeIt(const SymListGraph& g) 
deba@937
   658
	: SymListGraph::Parent::EdgeIt(g) {}
deba@937
   659
deba@937
   660
      SymEdgeIt(const SymListGraph& g, SymEdge e) 
deba@937
   661
	: SymListGraph::Parent::EdgeIt(g, e) {}
deba@937
   662
deba@937
   663
      SymEdgeIt(Invalid i) 
deba@937
   664
	: SymListGraph::Parent::EdgeIt(INVALID) {}
deba@937
   665
deba@937
   666
      SymEdgeIt& operator++() {
deba@937
   667
	SymListGraph::Parent::EdgeIt::operator++();
deba@937
   668
	return *this;
deba@937
   669
      }
deba@937
   670
deba@937
   671
      operator SymEdge() const {
deba@937
   672
	return SymEdge
deba@937
   673
	  (static_cast<const SymListGraph::Parent::EdgeIt&>(*this));
deba@937
   674
      }
deba@937
   675
      bool operator==(const SymEdge i) const {return SymEdge(*this) == i;}
deba@937
   676
      bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;}
deba@937
   677
      bool operator<(const SymEdge i) const {return SymEdge(*this) < i;}
deba@937
   678
    };
deba@937
   679
deba@937
   680
    class EdgeIt {
deba@937
   681
      SymEdgeIt it;
deba@937
   682
      bool fw;
deba@937
   683
    public:
deba@937
   684
      EdgeIt(const SymListGraph& g) : it(g), fw(true) {}
deba@937
   685
      EdgeIt (Invalid i) : it(i) { }
deba@937
   686
      EdgeIt(const SymListGraph& g, Edge e) 
deba@937
   687
	: it(g, SymEdge(e)), fw(id(e) & 1 == 0) { }
deba@937
   688
      EdgeIt() { }
deba@937
   689
      EdgeIt& operator++() {
deba@937
   690
	fw = !fw;
deba@937
   691
	if (fw) ++it;
deba@937
   692
	return *this;
deba@937
   693
      }
deba@937
   694
      operator Edge() const {
deba@937
   695
	if (it == INVALID) return INVALID;
deba@937
   696
	return fw ? forward(it) : backward(it);
deba@937
   697
      }
deba@937
   698
      bool operator==(const Edge i) const {return Edge(*this) == i;}
deba@937
   699
      bool operator!=(const Edge i) const {return Edge(*this) != i;}
deba@937
   700
      bool operator<(const Edge i) const {return Edge(*this) < i;}
deba@937
   701
deba@937
   702
    };
deba@937
   703
deba@937
   704
    ///Number of nodes.
deba@937
   705
    int nodeNum() const { return Parent::nodeNum(); }
deba@937
   706
    ///Number of edges.
deba@937
   707
    int edgeNum() const { return 2*Parent::edgeNum(); }
deba@937
   708
    ///Number of symmetric edges.
deba@937
   709
    int symEdgeNum() const { return Parent::edgeNum(); }
deba@937
   710
deba@937
   711
    ///Set the expected maximum number of edges.
deba@937
   712
deba@937
   713
    ///With this function, it is possible to set the expected number of edges.
deba@937
   714
    ///The use of this fasten the building of the graph and makes
deba@937
   715
    ///it possible to avoid the superfluous memory allocation.
deba@937
   716
    void reserveSymEdge(int n) { Parent::reserveEdge(n); };
deba@937
   717
    
deba@937
   718
    /// Maximum node ID.
deba@937
   719
    
deba@937
   720
    /// Maximum node ID.
deba@937
   721
    ///\sa id(Node)
deba@937
   722
    int maxNodeId() const { return Parent::maxNodeId(); } 
deba@937
   723
    /// Maximum edge ID.
deba@937
   724
    
deba@937
   725
    /// Maximum edge ID.
deba@937
   726
    ///\sa id(Edge)
deba@937
   727
    int maxEdgeId() const { return 2*Parent::maxEdgeId(); }
deba@937
   728
    /// Maximum symmetric edge ID.
deba@937
   729
    
deba@937
   730
    /// Maximum symmetric edge ID.
deba@937
   731
    ///\sa id(SymEdge)
deba@937
   732
    int maxSymEdgeId() const { return Parent::maxEdgeId(); }
deba@937
   733
deba@937
   734
deba@937
   735
    Node tail(Edge e) const { 
deba@937
   736
      return (e.id & 1) == 0 ? 
deba@937
   737
	Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e)); 
deba@937
   738
    }
deba@937
   739
deba@937
   740
    Node head(Edge e) const { 
deba@937
   741
      return (e.id & 1) == 0 ? 
deba@937
   742
	Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e)); 
deba@937
   743
    }
deba@937
   744
deba@937
   745
    Node tail(SymEdge e) const { 
deba@937
   746
      return Parent::tail(e); 
deba@937
   747
    }
deba@937
   748
deba@937
   749
    Node head(SymEdge e) const { 
deba@937
   750
      return Parent::head(e); 
deba@937
   751
    }
deba@937
   752
deba@937
   753
    NodeIt& first(NodeIt& v) const { 
deba@937
   754
      v=NodeIt(*this); return v; }
deba@937
   755
    EdgeIt& first(EdgeIt& e) const { 
deba@937
   756
      e=EdgeIt(*this); return e; }
deba@937
   757
    SymEdgeIt& first(SymEdgeIt& e) const {
deba@937
   758
      e=SymEdgeIt(*this); return e; }
deba@937
   759
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
deba@937
   760
      e=OutEdgeIt(*this,v); return e; }
deba@937
   761
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
deba@937
   762
      e=InEdgeIt(*this,v); return e; }
deba@937
   763
deba@937
   764
    /// Node ID.
deba@937
   765
    
deba@937
   766
    /// The ID of a valid Node is a nonnegative integer not greater than
deba@937
   767
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
deba@937
   768
    /// and the greatest node ID can be actually less then \ref maxNodeId().
deba@937
   769
    ///
deba@937
   770
    /// The ID of the \ref INVALID node is -1.
deba@937
   771
    ///\return The ID of the node \c v. 
deba@937
   772
    static int id(Node v) { return Parent::id(v); }
deba@937
   773
    /// Edge ID.
deba@937
   774
    
deba@937
   775
    /// The ID of a valid Edge is a nonnegative integer not greater than
deba@937
   776
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
deba@937
   777
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
deba@937
   778
    ///
deba@937
   779
    /// The ID of the \ref INVALID edge is -1.
deba@937
   780
    ///\return The ID of the edge \c e. 
deba@937
   781
    static int id(Edge e) { return e.id; }
deba@937
   782
deba@937
   783
    /// The ID of a valid SymEdge is a nonnegative integer not greater than
deba@937
   784
    /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous
deba@937
   785
    /// and the greatest edge ID can be actually less then \ref maxSymEdgeId().
deba@937
   786
    ///
deba@937
   787
    /// The ID of the \ref INVALID symmetric edge is -1.
deba@937
   788
    ///\return The ID of the edge \c e. 
deba@937
   789
    static int id(SymEdge e) { return Parent::id(e); }
deba@937
   790
deba@937
   791
    /// Adds a new node to the graph.
deba@937
   792
deba@937
   793
    /// \warning It adds the new node to the front of the list.
deba@937
   794
    /// (i.e. the lastly added node becomes the first.)
deba@937
   795
    Node addNode() {
deba@937
   796
      return Parent::addNode();
deba@937
   797
    }
deba@937
   798
    
deba@937
   799
    SymEdge addEdge(Node u, Node v) {
deba@937
   800
      SymEdge se = Parent::addEdge(u, v);
deba@937
   801
      edge_maps.add(forward(se));
deba@937
   802
      edge_maps.add(backward(se));
deba@937
   803
      return se;
deba@937
   804
    }
deba@937
   805
    
deba@937
   806
    /// Finds an edge between two nodes.
deba@937
   807
deba@937
   808
    /// Finds an edge from node \c u to node \c v.
deba@937
   809
    ///
deba@937
   810
    /// If \c prev is \ref INVALID (this is the default value), then
deba@937
   811
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
deba@937
   812
    /// the next edge from \c u to \c v after \c prev.
deba@937
   813
    /// \return The found edge or INVALID if there is no such an edge.
deba@937
   814
    Edge findEdge(Node u, Node v, Edge prev = INVALID) 
deba@937
   815
    {     
deba@937
   816
      if (prev == INVALID || id(prev) & 1 == 0) {
deba@937
   817
	SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
deba@937
   818
	if (se != INVALID) return forward(se);
deba@937
   819
      } else {
deba@937
   820
	SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
deba@937
   821
	if (se != INVALID) return backward(se);	
deba@937
   822
      }
deba@937
   823
      return INVALID;
deba@937
   824
    }
deba@937
   825
deba@937
   826
//     /// Finds an symmetric edge between two nodes.
deba@937
   827
deba@937
   828
//     /// Finds an symmetric edge from node \c u to node \c v.
deba@937
   829
//     ///
deba@937
   830
//     /// If \c prev is \ref INVALID (this is the default value), then
deba@937
   831
//     /// It finds the first edge from \c u to \c v. Otherwise it looks for
deba@937
   832
//     /// the next edge from \c u to \c v after \c prev.
deba@937
   833
//     /// \return The found edge or INVALID if there is no such an edge.
deba@937
   834
deba@937
   835
//     SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID) 
deba@937
   836
//     {     
deba@937
   837
//       if (prev == INVALID || id(prev) & 1 == 0) {
deba@937
   838
// 	SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
deba@937
   839
// 	if (se != INVALID) return se;
deba@937
   840
//       } else {
deba@937
   841
// 	SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
deba@937
   842
// 	if (se != INVALID) return se;	
deba@937
   843
//       }
deba@937
   844
//       return INVALID;
deba@937
   845
//     }
deba@937
   846
    
deba@937
   847
  public:
deba@937
   848
deba@937
   849
    void erase(Node n) {      
deba@937
   850
      for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
deba@937
   851
	edge_maps.erase(it);
deba@937
   852
	edge_maps.erase(opposite(it));
deba@937
   853
      }
deba@937
   854
      Parent::erase(n);
deba@937
   855
    }
deba@937
   856
    
deba@937
   857
    void erase(SymEdge e) { 
deba@937
   858
      edge_maps.erase(forward(e));
deba@937
   859
      edge_maps.erase(backward(e));
deba@937
   860
      Parent::erase(e); 
deba@937
   861
    };
deba@937
   862
deba@937
   863
    void clear() {
deba@937
   864
      edge_maps.clear();
deba@937
   865
      Parent::clear();
deba@937
   866
    }
deba@937
   867
deba@937
   868
    static Edge opposite(Edge e) {
deba@937
   869
      return Edge(id(e) ^ 1);
deba@937
   870
    }
deba@937
   871
deba@937
   872
    static Edge forward(SymEdge e) {
deba@937
   873
      return Edge(id(e) << 1);
deba@937
   874
    }
deba@937
   875
deba@937
   876
    static Edge backward(SymEdge e) {
deba@937
   877
      return Edge((id(e) << 1) | 1);
deba@937
   878
    }
deba@937
   879
alpar@919
   880
  };
deba@909
   881
alpar@401
   882
  ///A graph class containing only nodes.
alpar@400
   883
alpar@401
   884
  ///This class implements a graph structure without edges.
alpar@401
   885
  ///The most useful application of this class is to be the node set of an
alpar@401
   886
  ///\ref EdgeSet class.
alpar@400
   887
  ///
alpar@880
   888
  ///It conforms to 
alpar@880
   889
  ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept
alpar@880
   890
  ///with the exception that you cannot
alpar@401
   891
  ///add (or delete) edges. The usual edge iterators are exists, but they are
alpar@401
   892
  ///always \ref INVALID.
alpar@880
   893
  ///\sa skeleton::ExtendableGraph
alpar@880
   894
  ///\sa EdgeSet
alpar@400
   895
  class NodeSet {
alpar@400
   896
alpar@400
   897
    //Nodes are double linked.
alpar@400
   898
    //The free nodes are only single linked using the "next" field.
alpar@400
   899
    struct NodeT 
alpar@400
   900
    {
alpar@400
   901
      int first_in,first_out;
alpar@400
   902
      int prev, next;
alpar@400
   903
      //      NodeT() {}
alpar@400
   904
    };
alpar@400
   905
alpar@400
   906
    std::vector<NodeT> nodes;
alpar@400
   907
    //The first node
alpar@400
   908
    int first_node;
alpar@400
   909
    //The first free node
alpar@400
   910
    int first_free_node;
alpar@400
   911
    
alpar@400
   912
  public:
deba@782
   913
deba@782
   914
    typedef NodeSet Graph;
alpar@400
   915
    
alpar@400
   916
    class Node;
alpar@400
   917
    class Edge;
alpar@400
   918
alpar@400
   919
  public:
alpar@400
   920
alpar@400
   921
    class NodeIt;
alpar@400
   922
    class EdgeIt;
alpar@400
   923
    class OutEdgeIt;
alpar@400
   924
    class InEdgeIt;
alpar@400
   925
    
alpar@904
   926
    // Create node map registry.
deba@822
   927
    CREATE_NODE_MAP_REGISTRY;
alpar@904
   928
    // Create node maps.
deba@897
   929
    CREATE_NODE_MAP(ArrayMap);
deba@822
   930
deba@822
   931
    /// Creating empty map structure for edges.
deba@822
   932
    template <typename Value>
deba@822
   933
    class EdgeMap {
deba@822
   934
    public:
deba@822
   935
      EdgeMap(const Graph&) {}
deba@822
   936
      EdgeMap(const Graph&, const Value&) {}
deba@822
   937
deba@822
   938
      EdgeMap(const EdgeMap&) {}
deba@822
   939
      template <typename CMap> EdgeMap(const CMap&) {}
deba@822
   940
deba@822
   941
      EdgeMap& operator=(const EdgeMap&) {}
deba@822
   942
      template <typename CMap> EdgeMap& operator=(const CMap&) {}
deba@822
   943
      
deba@822
   944
      class ConstIterator {
deba@822
   945
      public:
deba@822
   946
	bool operator==(const ConstIterator&) {return true;}
deba@822
   947
	bool operator!=(const ConstIterator&) {return false;}
deba@822
   948
      };
deba@822
   949
deba@822
   950
      typedef ConstIterator Iterator;
deba@822
   951
      
deba@822
   952
      Iterator begin() { return Iterator();}
deba@822
   953
      Iterator end() { return Iterator();}
deba@822
   954
deba@822
   955
      ConstIterator begin() const { return ConstIterator();}
deba@822
   956
      ConstIterator end() const { return ConstIterator();}
deba@822
   957
deba@822
   958
    };
alpar@400
   959
    
alpar@400
   960
  public:
alpar@400
   961
alpar@408
   962
    ///Default constructor
deba@782
   963
    NodeSet() 
deba@782
   964
      : nodes(), first_node(-1), first_free_node(-1) {}
alpar@408
   965
    ///Copy constructor
deba@782
   966
    NodeSet(const NodeSet &_g) 
deba@782
   967
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   968
	first_free_node(_g.first_free_node) {}
alpar@400
   969
    
alpar@813
   970
    ///Number of nodes.
alpar@813
   971
    int nodeNum() const { return nodes.size(); }
alpar@813
   972
    ///Number of edges.
alpar@813
   973
    int edgeNum() const { return 0; }
alpar@400
   974
alpar@813
   975
    /// Maximum node ID.
alpar@813
   976
    
alpar@813
   977
    /// Maximum node ID.
alpar@813
   978
    ///\sa id(Node)
alpar@813
   979
    int maxNodeId() const { return nodes.size()-1; }
alpar@813
   980
    /// Maximum edge ID.
alpar@813
   981
    
alpar@813
   982
    /// Maximum edge ID.
alpar@813
   983
    ///\sa id(Edge)
alpar@813
   984
    int maxEdgeId() const { return 0; }
alpar@400
   985
alpar@400
   986
    Node tail(Edge e) const { return INVALID; }
alpar@400
   987
    Node head(Edge e) const { return INVALID; }
alpar@400
   988
alpar@400
   989
    NodeIt& first(NodeIt& v) const { 
alpar@400
   990
      v=NodeIt(*this); return v; }
alpar@400
   991
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   992
      e=EdgeIt(*this); return e; }
alpar@400
   993
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   994
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   995
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   996
      e=InEdgeIt(*this,v); return e; }
alpar@400
   997
alpar@813
   998
    /// Node ID.
alpar@813
   999
    
alpar@813
  1000
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
  1001
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
  1002
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
  1003
    ///
alpar@813
  1004
    /// The ID of the \ref INVALID node is -1.
alpar@813
  1005
    ///\return The ID of the node \c v. 
alpar@905
  1006
    static int id(Node v) { return v.n; }
alpar@813
  1007
    /// Edge ID.
alpar@813
  1008
    
alpar@813
  1009
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
  1010
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
  1011
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
  1012
    ///
alpar@813
  1013
    /// The ID of the \ref INVALID edge is -1.
alpar@813
  1014
    ///\return The ID of the edge \c e. 
alpar@905
  1015
    static int id(Edge e) { return -1; }
alpar@400
  1016
alpar@400
  1017
    /// Adds a new node to the graph.
alpar@400
  1018
alpar@813
  1019
    /// \warning It adds the new node to the front of the list.
alpar@400
  1020
    /// (i.e. the lastly added node becomes the first.)
alpar@400
  1021
    Node addNode() {
alpar@400
  1022
      int n;
alpar@400
  1023
      
alpar@400
  1024
      if(first_free_node==-1)
alpar@400
  1025
	{
alpar@400
  1026
	  n = nodes.size();
alpar@400
  1027
	  nodes.push_back(NodeT());
alpar@400
  1028
	}
alpar@400
  1029
      else {
alpar@400
  1030
	n = first_free_node;
alpar@400
  1031
	first_free_node = nodes[n].next;
alpar@400
  1032
      }
alpar@400
  1033
      
alpar@400
  1034
      nodes[n].next = first_node;
alpar@400
  1035
      if(first_node != -1) nodes[first_node].prev = n;
alpar@400
  1036
      first_node = n;
alpar@400
  1037
      nodes[n].prev = -1;
alpar@400
  1038
      
alpar@400
  1039
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@400
  1040
      
alpar@400
  1041
      Node nn; nn.n=n;
alpar@400
  1042
alpar@400
  1043
      //Update dynamic maps
deba@782
  1044
      node_maps.add(nn);
alpar@400
  1045
alpar@400
  1046
      return nn;
alpar@400
  1047
    }
alpar@400
  1048
    
alpar@400
  1049
    void erase(Node nn) {
alpar@400
  1050
      int n=nn.n;
alpar@400
  1051
      
alpar@400
  1052
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@400
  1053
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@400
  1054
      else first_node = nodes[n].next;
alpar@400
  1055
      
alpar@400
  1056
      nodes[n].next = first_free_node;
alpar@400
  1057
      first_free_node = n;
alpar@400
  1058
alpar@400
  1059
      //Update dynamic maps
deba@782
  1060
      node_maps.erase(nn);
alpar@400
  1061
    }
alpar@400
  1062
    
alpar@774
  1063
        
alpar@774
  1064
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
  1065
    {
alpar@774
  1066
      return INVALID;
alpar@774
  1067
    }
alpar@774
  1068
    
alpar@400
  1069
    void clear() {
deba@782
  1070
      node_maps.clear();
alpar@400
  1071
      nodes.clear();
alpar@400
  1072
      first_node = first_free_node = -1;
alpar@400
  1073
    }
alpar@400
  1074
alpar@400
  1075
    class Node {
alpar@400
  1076
      friend class NodeSet;
alpar@400
  1077
      template <typename T> friend class NodeMap;
alpar@400
  1078
      
alpar@400
  1079
      friend class Edge;
alpar@400
  1080
      friend class OutEdgeIt;
alpar@400
  1081
      friend class InEdgeIt;
alpar@400
  1082
alpar@400
  1083
    protected:
alpar@400
  1084
      int n;
alpar@905
  1085
      friend int NodeSet::id(Node v); 
alpar@400
  1086
      Node(int nn) {n=nn;}
alpar@400
  1087
    public:
alpar@400
  1088
      Node() {}
alpar@400
  1089
      Node (Invalid i) { n=-1; }
alpar@400
  1090
      bool operator==(const Node i) const {return n==i.n;}
alpar@400
  1091
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@400
  1092
      bool operator<(const Node i) const {return n<i.n;}
alpar@400
  1093
    };
alpar@400
  1094
    
alpar@400
  1095
    class NodeIt : public Node {
alpar@774
  1096
      const NodeSet *G;
alpar@400
  1097
      friend class NodeSet;
alpar@400
  1098
    public:
alpar@579
  1099
      NodeIt() : Node() { }
alpar@774
  1100
      NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
alpar@579
  1101
      NodeIt(Invalid i) : Node(i) { }
alpar@774
  1102
      NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
  1103
      NodeIt &operator++() {
alpar@774
  1104
	n=G->nodes[n].next; 
alpar@774
  1105
	return *this; 
alpar@774
  1106
      }
alpar@400
  1107
    };
alpar@400
  1108
alpar@400
  1109
    class Edge {
alpar@400
  1110
    public:
alpar@400
  1111
      Edge() { }
alpar@400
  1112
      Edge (Invalid) { }
alpar@400
  1113
      bool operator==(const Edge i) const {return true;}
alpar@400
  1114
      bool operator!=(const Edge i) const {return false;}
alpar@400
  1115
      bool operator<(const Edge i) const {return false;}
alpar@400
  1116
    };
alpar@400
  1117
    
alpar@400
  1118
    class EdgeIt : public Edge {
alpar@400
  1119
    public:
alpar@400
  1120
      EdgeIt(const NodeSet& G) : Edge() { }
alpar@774
  1121
      EdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
  1122
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1123
      EdgeIt() : Edge() { }
alpar@774
  1124
      EdgeIt operator++() { return INVALID; }
alpar@400
  1125
    };
alpar@400
  1126
    
alpar@400
  1127
    class OutEdgeIt : public Edge {
alpar@400
  1128
      friend class NodeSet;
alpar@400
  1129
    public: 
alpar@400
  1130
      OutEdgeIt() : Edge() { }
alpar@774
  1131
      OutEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
  1132
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1133
      OutEdgeIt(const NodeSet& G,const Node v)	: Edge() {}
alpar@774
  1134
      OutEdgeIt operator++() { return INVALID; }
alpar@400
  1135
    };
alpar@400
  1136
    
alpar@400
  1137
    class InEdgeIt : public Edge {
alpar@400
  1138
      friend class NodeSet;
alpar@400
  1139
    public: 
alpar@400
  1140
      InEdgeIt() : Edge() { }
alpar@774
  1141
      InEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
  1142
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1143
      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
alpar@774
  1144
      InEdgeIt operator++() { return INVALID; }
alpar@400
  1145
    };
alpar@400
  1146
alpar@400
  1147
  };
alpar@400
  1148
alpar@400
  1149
alpar@400
  1150
alpar@401
  1151
  ///Graph structure using a node set of another graph.
alpar@401
  1152
alpar@401
  1153
  ///This structure can be used to establish another graph over a node set
alpar@401
  1154
  /// of an existing one. The node iterator will go through the nodes of the
alpar@401
  1155
  /// original graph, and the NodeMap's of both graphs will convert to
alpar@401
  1156
  /// each other.
alpar@401
  1157
  ///
alpar@404
  1158
  ///\warning Adding or deleting nodes from the graph is not safe if an
alpar@404
  1159
  ///\ref EdgeSet is currently attached to it!
alpar@404
  1160
  ///
alpar@404
  1161
  ///\todo Make it possible to add/delete edges from the base graph
alpar@404
  1162
  ///(and from \ref EdgeSet, as well)
alpar@404
  1163
  ///
alpar@401
  1164
  ///\param GG The type of the graph which shares its node set with this class.
alpar@880
  1165
  ///Its interface must conform to the
alpar@880
  1166
  ///\ref skeleton::StaticGraph "StaticGraph" concept.
alpar@400
  1167
  ///
alpar@880
  1168
  ///It conforms to the 
alpar@880
  1169
  ///\ref skeleton::ExtendableGraph "ExtendableGraph" concept.
alpar@880
  1170
  ///\sa skeleton::ExtendableGraph.
alpar@880
  1171
  ///\sa NodeSet.
alpar@400
  1172
  template<typename GG>
alpar@400
  1173
  class EdgeSet {
alpar@400
  1174
alpar@400
  1175
    typedef GG NodeGraphType;
alpar@400
  1176
alpar@400
  1177
    NodeGraphType &G;
alpar@400
  1178
alpar@515
  1179
  public:
deba@782
  1180
alpar@400
  1181
    class Node;
alpar@705
  1182
    class Edge;
alpar@705
  1183
    class OutEdgeIt;
alpar@705
  1184
    class InEdgeIt;
alpar@705
  1185
    class SymEdge;
deba@782
  1186
deba@782
  1187
    typedef EdgeSet Graph;
deba@782
  1188
alpar@531
  1189
    int id(Node v) const; 
alpar@531
  1190
alpar@531
  1191
    class Node : public NodeGraphType::Node {
alpar@531
  1192
      friend class EdgeSet;
alpar@531
  1193
      
alpar@531
  1194
      friend class Edge;
alpar@531
  1195
      friend class OutEdgeIt;
alpar@531
  1196
      friend class InEdgeIt;
alpar@531
  1197
      friend class SymEdge;
alpar@531
  1198
alpar@531
  1199
    public:
alpar@531
  1200
      friend int EdgeSet::id(Node v) const; 
alpar@531
  1201
    public:
alpar@531
  1202
      Node() : NodeGraphType::Node() {}
alpar@531
  1203
      Node (Invalid i) : NodeGraphType::Node(i) {}
alpar@531
  1204
      Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
alpar@531
  1205
    };
alpar@531
  1206
    
alpar@531
  1207
    class NodeIt : public NodeGraphType::NodeIt {
alpar@531
  1208
      friend class EdgeSet;
alpar@531
  1209
    public:
alpar@531
  1210
      NodeIt() : NodeGraphType::NodeIt() { }
alpar@774
  1211
      NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
alpar@531
  1212
      NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
alpar@531
  1213
      NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
alpar@531
  1214
      NodeIt(const typename NodeGraphType::NodeIt &n)
alpar@531
  1215
	: NodeGraphType::NodeIt(n) {}
alpar@579
  1216
alpar@531
  1217
      operator Node() { return Node(*this);}
alpar@774
  1218
      NodeIt &operator++()
alpar@774
  1219
      { this->NodeGraphType::NodeIt::operator++(); return *this;} 
alpar@531
  1220
    };
alpar@515
  1221
alpar@515
  1222
  private:
alpar@400
  1223
    //Edges are double linked.
alpar@400
  1224
    //The free edges are only single linked using the "next_in" field.
alpar@400
  1225
    struct NodeT 
alpar@400
  1226
    {
alpar@400
  1227
      int first_in,first_out;
alpar@400
  1228
      NodeT() : first_in(-1), first_out(-1) { }
alpar@400
  1229
    };
alpar@400
  1230
alpar@400
  1231
    struct EdgeT 
alpar@400
  1232
    {
alpar@400
  1233
      Node head, tail;
alpar@400
  1234
      int prev_in, prev_out;
alpar@400
  1235
      int next_in, next_out;
alpar@400
  1236
    };
alpar@400
  1237
alpar@400
  1238
    
alpar@515
  1239
    typename NodeGraphType::template NodeMap<NodeT> nodes;
alpar@400
  1240
    
alpar@400
  1241
    std::vector<EdgeT> edges;
alpar@400
  1242
    //The first free edge
alpar@400
  1243
    int first_free_edge;
alpar@400
  1244
    
alpar@400
  1245
  public:
alpar@400
  1246
    
alpar@400
  1247
    class Node;
alpar@400
  1248
    class Edge;
alpar@400
  1249
alpar@400
  1250
    class NodeIt;
alpar@400
  1251
    class EdgeIt;
alpar@400
  1252
    class OutEdgeIt;
alpar@400
  1253
    class InEdgeIt;
deba@782
  1254
deba@782
  1255
alpar@904
  1256
    // Create edge map registry.
deba@782
  1257
    CREATE_EDGE_MAP_REGISTRY;
alpar@904
  1258
    // Create edge maps.
deba@897
  1259
    CREATE_EDGE_MAP(ArrayMap);
deba@822
  1260
alpar@904
  1261
    // Import node maps from the NodeGraphType.
deba@822
  1262
    IMPORT_NODE_MAP(NodeGraphType, graph.G, EdgeSet, graph);
alpar@400
  1263
    
alpar@400
  1264
    
alpar@400
  1265
  public:
alpar@400
  1266
alpar@408
  1267
    ///Constructor
alpar@408
  1268
    
alpar@408
  1269
    ///Construates a new graph based on the nodeset of an existing one.
alpar@408
  1270
    ///\param _G the base graph.
alpar@880
  1271
    explicit EdgeSet(NodeGraphType &_G) 
deba@782
  1272
      : G(_G), nodes(_G), edges(),
deba@782
  1273
	first_free_edge(-1) {}
alpar@408
  1274
    ///Copy constructor
alpar@408
  1275
alpar@408
  1276
    ///Makes a copy of an EdgeSet.
alpar@408
  1277
    ///It will be based on the same graph.
alpar@880
  1278
    explicit EdgeSet(const EdgeSet &_g) 
deba@782
  1279
      : G(_g.G), nodes(_g.G), edges(_g.edges),
deba@782
  1280
	first_free_edge(_g.first_free_edge) {}
alpar@400
  1281
    
alpar@813
  1282
    ///Number of nodes.
alpar@813
  1283
    int nodeNum() const { return G.nodeNum(); }
alpar@813
  1284
    ///Number of edges.
alpar@813
  1285
    int edgeNum() const { return edges.size(); }
alpar@400
  1286
alpar@813
  1287
    /// Maximum node ID.
alpar@813
  1288
    
alpar@813
  1289
    /// Maximum node ID.
alpar@813
  1290
    ///\sa id(Node)
alpar@813
  1291
    int maxNodeId() const { return G.maxNodeId(); }
alpar@813
  1292
    /// Maximum edge ID.
alpar@813
  1293
    
alpar@813
  1294
    /// Maximum edge ID.
alpar@813
  1295
    ///\sa id(Edge)
alpar@813
  1296
    int maxEdgeId() const { return edges.size()-1; }
alpar@400
  1297
alpar@400
  1298
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@400
  1299
    Node head(Edge e) const { return edges[e.n].head; }
alpar@400
  1300
alpar@400
  1301
    NodeIt& first(NodeIt& v) const { 
alpar@400
  1302
      v=NodeIt(*this); return v; }
alpar@400
  1303
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
  1304
      e=EdgeIt(*this); return e; }
alpar@400
  1305
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
  1306
      e=OutEdgeIt(*this,v); return e; }
alpar@400
  1307
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
  1308
      e=InEdgeIt(*this,v); return e; }
alpar@400
  1309
alpar@813
  1310
    /// Node ID.
alpar@813
  1311
    
alpar@813
  1312
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
  1313
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
  1314
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
  1315
    ///
alpar@813
  1316
    /// The ID of the \ref INVALID node is -1.
alpar@813
  1317
    ///\return The ID of the node \c v. 
alpar@813
  1318
    int id(Node v) { return G.id(v); }
alpar@813
  1319
    /// Edge ID.
alpar@813
  1320
    
alpar@813
  1321
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
  1322
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
  1323
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
  1324
    ///
alpar@813
  1325
    /// The ID of the \ref INVALID edge is -1.
alpar@813
  1326
    ///\return The ID of the edge \c e. 
alpar@905
  1327
    static int id(Edge e) { return e.n; }
alpar@400
  1328
alpar@400
  1329
    /// Adds a new node to the graph.
alpar@579
  1330
    Node addNode() { return G.addNode(); }
alpar@400
  1331
    
alpar@400
  1332
    Edge addEdge(Node u, Node v) {
alpar@400
  1333
      int n;
alpar@400
  1334
      
alpar@400
  1335
      if(first_free_edge==-1)
alpar@400
  1336
	{
alpar@400
  1337
	  n = edges.size();
alpar@400
  1338
	  edges.push_back(EdgeT());
alpar@400
  1339
	}
alpar@400
  1340
      else {
alpar@400
  1341
	n = first_free_edge;
alpar@400
  1342
	first_free_edge = edges[n].next_in;
alpar@400
  1343
      }
alpar@400
  1344
      
alpar@401
  1345
      edges[n].tail = u; edges[n].head = v;
alpar@400
  1346
alpar@401
  1347
      edges[n].next_out = nodes[u].first_out;
alpar@401
  1348
      if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
alpar@401
  1349
      edges[n].next_in = nodes[v].first_in;
alpar@401
  1350
      if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
alpar@400
  1351
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@400
  1352
	
alpar@401
  1353
      nodes[u].first_out = nodes[v].first_in = n;
alpar@400
  1354
alpar@400
  1355
      Edge e; e.n=n;
alpar@400
  1356
alpar@400
  1357
      //Update dynamic maps
deba@782
  1358
      edge_maps.add(e);
alpar@400
  1359
alpar@400
  1360
      return e;
alpar@400
  1361
    }
alpar@400
  1362
alpar@774
  1363
    /// Finds an edge between two nodes.
alpar@774
  1364
alpar@774
  1365
    /// Finds an edge from node \c u to node \c v.
alpar@774
  1366
    ///
alpar@774
  1367
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
  1368
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
  1369
    /// the next edge from \c u to \c v after \c prev.
alpar@774
  1370
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
  1371
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
  1372
    {
alpar@774
  1373
      int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
alpar@774
  1374
      while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
alpar@774
  1375
      prev.n=e;
alpar@774
  1376
      return prev;
alpar@774
  1377
    }
alpar@774
  1378
    
alpar@400
  1379
  private:
alpar@400
  1380
    void eraseEdge(int n) {
alpar@400
  1381
      
alpar@400
  1382
      if(edges[n].next_in!=-1)
alpar@400
  1383
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@400
  1384
      if(edges[n].prev_in!=-1)
alpar@400
  1385
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@400
  1386
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@400
  1387
      
alpar@400
  1388
      if(edges[n].next_out!=-1)
alpar@400
  1389
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@400
  1390
      if(edges[n].prev_out!=-1)
alpar@400
  1391
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@400
  1392
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@400
  1393
      
alpar@400
  1394
      edges[n].next_in = first_free_edge;
alpar@400
  1395
      first_free_edge = -1;      
alpar@400
  1396
alpar@400
  1397
      //Update dynamic maps
deba@782
  1398
      Edge e; e.n = n;
deba@782
  1399
      edge_maps.erase(e);
alpar@400
  1400
    }
alpar@400
  1401
      
alpar@400
  1402
  public:
alpar@400
  1403
alpar@400
  1404
    void erase(Edge e) { eraseEdge(e.n); }
alpar@400
  1405
alpar@579
  1406
    ///Clear all edges. (Doesn't clear the nodes!)
alpar@579
  1407
    void clear() {
deba@782
  1408
      edge_maps.clear();
alpar@579
  1409
      edges.clear();
alpar@579
  1410
      first_free_edge=-1;
alpar@579
  1411
    }
alpar@579
  1412
alpar@579
  1413
alpar@400
  1414
    class Edge {
alpar@579
  1415
    public:
alpar@400
  1416
      friend class EdgeSet;
alpar@400
  1417
      template <typename T> friend class EdgeMap;
alpar@400
  1418
alpar@400
  1419
      friend class Node;
alpar@400
  1420
      friend class NodeIt;
alpar@905
  1421
    protected:
alpar@579
  1422
      int n;
alpar@400
  1423
      friend int EdgeSet::id(Edge e) const;
alpar@400
  1424
alpar@400
  1425
      Edge(int nn) {n=nn;}
alpar@400
  1426
    public:
alpar@400
  1427
      Edge() { }
alpar@400
  1428
      Edge (Invalid) { n=-1; }
alpar@400
  1429
      bool operator==(const Edge i) const {return n==i.n;}
alpar@400
  1430
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@400
  1431
      bool operator<(const Edge i) const {return n<i.n;}
alpar@400
  1432
    };
alpar@400
  1433
    
alpar@400
  1434
    class EdgeIt : public Edge {
alpar@400
  1435
      friend class EdgeSet;
alpar@579
  1436
      template <typename T> friend class EdgeMap;
alpar@579
  1437
    
alpar@774
  1438
      const EdgeSet *G;
alpar@400
  1439
    public:
alpar@774
  1440
      EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
alpar@503
  1441
        NodeIt m;
alpar@774
  1442
	for(G->first(m);
alpar@774
  1443
	    m!=INVALID && G->nodes[m].first_in == -1;  ++m);
alpar@774
  1444
	///\bug AJJAJ! This is a non sense!!!!!!!
alpar@774
  1445
	this->n = m!=INVALID?-1:G->nodes[m].first_in;
alpar@400
  1446
      }
alpar@774
  1447
      EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1448
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1449
      EdgeIt() : Edge() { }
alpar@774
  1450
      ///.
alpar@774
  1451
      
alpar@774
  1452
      ///\bug UNIMPLEMENTED!!!!!
alpar@774
  1453
      //
alpar@774
  1454
      EdgeIt &operator++() {
alpar@774
  1455
	return *this;
alpar@774
  1456
      }
alpar@400
  1457
    };
alpar@400
  1458
    
alpar@400
  1459
    class OutEdgeIt : public Edge {
alpar@774
  1460
      const EdgeSet *G;
alpar@400
  1461
      friend class EdgeSet;
alpar@400
  1462
    public: 
alpar@400
  1463
      OutEdgeIt() : Edge() { }
alpar@400
  1464
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1465
      OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1466
alpar@774
  1467
      OutEdgeIt(const EdgeSet& _G,const Node v) :
alpar@774
  1468
	Edge(_G.nodes[v].first_out), G(&_G) { }
deba@844
  1469
      OutEdgeIt &operator++() { 
deba@844
  1470
	Edge::n = G->edges[Edge::n].next_out;
deba@844
  1471
	return *this; 
deba@844
  1472
      }
alpar@400
  1473
    };
alpar@400
  1474
    
alpar@400
  1475
    class InEdgeIt : public Edge {
alpar@774
  1476
      const EdgeSet *G;
alpar@400
  1477
      friend class EdgeSet;
alpar@400
  1478
    public: 
alpar@400
  1479
      InEdgeIt() : Edge() { }
alpar@400
  1480
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1481
      InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@774
  1482
      InEdgeIt(const EdgeSet& _G,Node v)
alpar@774
  1483
	: Edge(_G.nodes[v].first_in), G(&_G) { }
deba@844
  1484
      InEdgeIt &operator++() { 
deba@844
  1485
	Edge::n = G->edges[Edge::n].next_in; 
deba@844
  1486
	return *this; 
deba@844
  1487
      }
alpar@400
  1488
    };
deba@782
  1489
    
alpar@400
  1490
  };
alpar@406
  1491
alpar@579
  1492
  template<typename GG>
alpar@579
  1493
  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
alpar@531
  1494
alpar@406
  1495
/// @}  
alpar@406
  1496
alpar@921
  1497
} //namespace lemon
alpar@395
  1498
alpar@921
  1499
#endif //LEMON_LIST_GRAPH_H