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