lemon/edge_set.h
author deba
Wed, 22 Feb 2006 18:26:56 +0000
changeset 1979 c2992fd74dad
parent 1962 c1c3a0fae8a1
child 1990 15fb7a4ea6be
permissions -rw-r--r--
Mergeing extendermerge branch
Changes:
the extender system
resize for static size graph
UGraphExtender => UndirectGraphExtender
UGraphExtenders with changed meaning
Some UGraphExtender /SubUGraphExtenders, DirectUGraphExtender/
GridGraph => GridUGraph
radix sort to ansi compatible
deba@1842
     1
/* -*- C++ -*-
deba@1842
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1842
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1842
     8
 *
deba@1842
     9
 * Permission to use, modify and distribute this software is granted
deba@1842
    10
 * provided that this copyright notice appears in all copies. For
deba@1842
    11
 * precise terms see the accompanying LICENSE file.
deba@1842
    12
 *
deba@1842
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1842
    14
 * express or implied, and with no claim as to its suitability for any
deba@1842
    15
 * purpose.
deba@1842
    16
 *
deba@1842
    17
 */
deba@1842
    18
deba@1842
    19
#ifndef LEMON_EDGE_SET_H
deba@1842
    20
#define LEMON_EDGE_SET_H
deba@1842
    21
deba@1979
    22
deba@1979
    23
#include <lemon/bits/edge_set_extender.h>
deba@1962
    24
deba@1842
    25
/// \ingroup graphs
deba@1842
    26
/// \file
deba@1842
    27
/// \brief EdgeSet classes.
deba@1842
    28
///
deba@1842
    29
/// Graphs which use another graph's node-set as own. 
deba@1842
    30
deba@1842
    31
namespace lemon {
deba@1842
    32
deba@1842
    33
  template <typename _Graph>
deba@1842
    34
  class ListEdgeSetBase {
deba@1842
    35
  public:
deba@1842
    36
deba@1842
    37
    typedef _Graph Graph;
deba@1842
    38
    typedef typename Graph::Node Node;
deba@1842
    39
    typedef typename Graph::NodeIt NodeIt;
deba@1842
    40
deba@1842
    41
  protected:
deba@1842
    42
deba@1842
    43
    struct NodeT {
deba@1842
    44
      int first_out, first_in;
deba@1842
    45
      NodeT() : first_out(-1), first_in(-1) {}
deba@1842
    46
    };
deba@1842
    47
deba@1842
    48
    typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
deba@1842
    49
deba@1842
    50
    NodesImplBase* nodes;
deba@1842
    51
deba@1842
    52
    struct EdgeT {
deba@1842
    53
      Node source, target;
deba@1842
    54
      int next_out, next_in;
deba@1842
    55
      int prev_out, prev_in;
deba@1842
    56
      EdgeT() : prev_out(-1), prev_in(-1) {}
deba@1842
    57
    };
deba@1842
    58
deba@1842
    59
    std::vector<EdgeT> edges;
deba@1842
    60
deba@1842
    61
    int first_edge;
deba@1842
    62
    int first_free_edge;
deba@1842
    63
deba@1842
    64
    const Graph* graph;
deba@1842
    65
deba@1842
    66
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1842
    67
      graph = &_graph;
deba@1842
    68
      nodes = &_nodes;
deba@1842
    69
    }
deba@1842
    70
    
deba@1842
    71
  public:
deba@1842
    72
deba@1842
    73
    class Edge {
deba@1842
    74
      friend class ListEdgeSetBase<Graph>;
deba@1842
    75
    protected:
deba@1842
    76
      Edge(int _id) : id(_id) {}
deba@1842
    77
      int id;
deba@1842
    78
    public:
deba@1842
    79
      Edge() {}
deba@1842
    80
      Edge(Invalid) : id(-1) {}
deba@1842
    81
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1842
    82
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1842
    83
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1842
    84
    };
deba@1842
    85
deba@1842
    86
    ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {} 
deba@1842
    87
deba@1842
    88
    Edge addEdge(const Node& source, const Node& target) {
deba@1842
    89
      int n;
deba@1842
    90
      if (first_free_edge == -1) {
deba@1842
    91
	n = edges.size();
deba@1842
    92
	edges.push_back(EdgeT());
deba@1842
    93
      } else {
deba@1842
    94
	n = first_free_edge;
deba@1842
    95
	first_free_edge = edges[first_free_edge].next_in;
deba@1842
    96
      }
deba@1842
    97
      edges[n].next_in = (*nodes)[target].first_in;
deba@1962
    98
      if ((*nodes)[target].first_in != -1) {
deba@1962
    99
        edges[(*nodes)[target].first_in].prev_in = n;
deba@1962
   100
      }
deba@1842
   101
      (*nodes)[target].first_in = n;
deba@1842
   102
      edges[n].next_out = (*nodes)[source].first_out;
deba@1962
   103
      if ((*nodes)[source].first_out != -1) {
deba@1962
   104
        edges[(*nodes)[source].first_out].prev_out = n;
deba@1962
   105
      }
deba@1842
   106
      (*nodes)[source].first_out = n;
deba@1842
   107
      edges[n].source = source;
deba@1842
   108
      edges[n].target = target;
deba@1842
   109
      return Edge(n);
deba@1842
   110
    }
deba@1842
   111
deba@1842
   112
    void erase(const Edge& edge) {
deba@1842
   113
      int n = edge.id;
deba@1842
   114
      if (edges[n].prev_in != -1) {
deba@1842
   115
	edges[edges[n].prev_in].next_in = edges[n].next_in;
deba@1842
   116
      } else {
deba@1842
   117
	(*nodes)[edges[n].target].first_in = edges[n].next_in;
deba@1842
   118
      }
deba@1842
   119
      if (edges[n].next_in != -1) {
deba@1842
   120
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
deba@1842
   121
      }
deba@1842
   122
deba@1842
   123
      if (edges[n].prev_out != -1) {
deba@1842
   124
	edges[edges[n].prev_out].next_out = edges[n].next_out;
deba@1842
   125
      } else {
deba@1842
   126
	(*nodes)[edges[n].source].first_out = edges[n].next_out;
deba@1842
   127
      }
deba@1842
   128
      if (edges[n].next_out != -1) {
deba@1842
   129
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
deba@1842
   130
      }
deba@1842
   131
           
deba@1842
   132
    }
deba@1842
   133
deba@1842
   134
    void clear() {
deba@1962
   135
      Node node;
deba@1962
   136
      for (first(node); node != INVALID; next(node)) {
deba@1962
   137
        (*nodes)[node].first_in = -1;
deba@1962
   138
        (*nodes)[node].first_out = -1;
deba@1962
   139
      }
deba@1842
   140
      edges.clear();
deba@1842
   141
      first_edge = -1;
deba@1842
   142
      first_free_edge = -1;
deba@1842
   143
    }
deba@1842
   144
deba@1842
   145
    void first(Node& node) const {
deba@1842
   146
      graph->first(node);
deba@1842
   147
    }
deba@1842
   148
deba@1842
   149
    void next(Node& node) const {
deba@1842
   150
      graph->next(node);
deba@1842
   151
    }
deba@1842
   152
deba@1842
   153
    void first(Edge& edge) const {
deba@1842
   154
      Node node;
deba@1842
   155
      for (first(node); node != INVALID && (*nodes)[node].first_in == -1; 
deba@1842
   156
	   next(node));
deba@1842
   157
      edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
deba@1842
   158
    }
deba@1842
   159
deba@1842
   160
    void next(Edge& edge) const {
deba@1842
   161
      if (edges[edge.id].next_in != -1) {
deba@1842
   162
	edge.id = edges[edge.id].next_in;
deba@1842
   163
      } else {
deba@1842
   164
	Node node = edges[edge.id].target;
deba@1842
   165
	for (next(node); node != INVALID && (*nodes)[node].first_in == -1; 
deba@1842
   166
	     next(node));
deba@1842
   167
	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
deba@1842
   168
      }      
deba@1842
   169
    }
deba@1842
   170
deba@1842
   171
    void firstOut(Edge& edge, const Node& node) const {
deba@1842
   172
      edge.id = (*nodes)[node].first_out;    
deba@1842
   173
    }
deba@1842
   174
    
deba@1842
   175
    void nextOut(Edge& edge) const {
deba@1842
   176
      edge.id = edges[edge.id].next_out;        
deba@1842
   177
    }
deba@1842
   178
deba@1842
   179
    void firstIn(Edge& edge, const Node& node) const {
deba@1842
   180
      edge.id = (*nodes)[node].first_in;          
deba@1842
   181
    }
deba@1842
   182
deba@1842
   183
    void nextIn(Edge& edge) const {
deba@1842
   184
      edge.id = edges[edge.id].next_in;    
deba@1842
   185
    }
deba@1842
   186
deba@1842
   187
    int id(const Node& node) const { return graph->id(node); }
deba@1842
   188
    int id(const Edge& edge) const { return edge.id; }
deba@1842
   189
deba@1962
   190
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@1842
   191
    Edge edgeFromId(int id) const { return Edge(id); }
deba@1842
   192
deba@1962
   193
    int maxNodeId() const { return graph->maxNodeId(); };
deba@1842
   194
    int maxEdgeId() const { return edges.size() - 1; }
deba@1842
   195
deba@1842
   196
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1842
   197
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1842
   198
deba@1842
   199
    template <typename _Value>
deba@1842
   200
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1842
   201
    public:
deba@1842
   202
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@1842
   203
      explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset) 
deba@1842
   204
	: Parent(*edgeset.graph) { }
deba@1842
   205
      NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1842
   206
	: Parent(*edgeset.graph, value) { }
deba@1842
   207
    };
deba@1842
   208
deba@1842
   209
  };
deba@1842
   210
deba@1866
   211
  /// \ingroup semi_adaptors
deba@1842
   212
  ///
deba@1842
   213
  /// \brief Graph using a node set of another graph and an
deba@1842
   214
  /// own edge set.
deba@1842
   215
  ///
deba@1842
   216
  /// This structure can be used to establish another graph over a node set
deba@1842
   217
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   218
  /// original graph.
deba@1842
   219
  ///
deba@1842
   220
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   221
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   222
  /// "StaticGraph" concept.
deba@1842
   223
  ///
deba@1842
   224
  /// In the edge extension and removing it conforms to the 
deba@1962
   225
  /// \ref concept::ErasableGraph "ErasableGraph" concept.
deba@1842
   226
  template <typename _Graph>
deba@1979
   227
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
deba@1842
   228
deba@1842
   229
  public:
deba@1842
   230
deba@1979
   231
    typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
deba@1842
   232
    
deba@1842
   233
    typedef typename Parent::Node Node;
deba@1842
   234
    typedef typename Parent::Edge Edge;
deba@1842
   235
    
deba@1842
   236
    typedef _Graph Graph;
deba@1842
   237
deba@1842
   238
deba@1842
   239
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   240
deba@1842
   241
    void eraseNode(const Node& node) {
deba@1842
   242
      Edge edge;
deba@1842
   243
      Parent::firstOut(edge, node);
deba@1842
   244
      while (edge != INVALID ) {
deba@1842
   245
	erase(edge);
deba@1842
   246
	Parent::firstOut(edge, node);
deba@1842
   247
      } 
deba@1842
   248
deba@1842
   249
      Parent::firstIn(edge, node);
deba@1842
   250
      while (edge != INVALID ) {
deba@1842
   251
	erase(edge);
deba@1842
   252
	Parent::firstIn(edge, node);
deba@1842
   253
      }
deba@1842
   254
    }
deba@1842
   255
    
deba@1842
   256
    void clearNodes() {
deba@1842
   257
      Parent::clear();
deba@1842
   258
    }
deba@1842
   259
deba@1842
   260
    class NodesImpl : public NodesImplBase {
deba@1842
   261
    public:
deba@1842
   262
      typedef NodesImplBase Parent;
deba@1842
   263
      
deba@1842
   264
      NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
deba@1842
   265
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   266
deba@1962
   267
      virtual ~NodesImpl() {}
deba@1842
   268
      
deba@1842
   269
    protected:
deba@1842
   270
deba@1842
   271
      virtual void erase(const Node& node) {
deba@1842
   272
	_edgeset.eraseNode(node);
deba@1842
   273
	Parent::erase(node);
deba@1842
   274
      }
deba@1962
   275
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   276
        for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   277
          _edgeset.eraseNode(nodes[i]);
deba@1962
   278
        }
deba@1962
   279
	Parent::erase(nodes);
deba@1962
   280
      }
deba@1842
   281
      virtual void clear() {
deba@1842
   282
	_edgeset.clearNodes();
deba@1842
   283
	Parent::clear();
deba@1842
   284
      }
deba@1842
   285
deba@1842
   286
    private:
deba@1842
   287
      ListEdgeSet& _edgeset;
deba@1842
   288
    };
deba@1842
   289
deba@1842
   290
    NodesImpl nodes;
deba@1842
   291
    
deba@1842
   292
  public:
deba@1842
   293
deba@1842
   294
    /// \brief Constructor of the adaptor.
deba@1842
   295
    /// 
deba@1842
   296
    /// Constructor of the adaptor.
deba@1842
   297
    ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   298
      Parent::initalize(graph, nodes);
deba@1842
   299
    }
deba@1842
   300
    
deba@1842
   301
  };
deba@1842
   302
deba@1866
   303
  /// \ingroup semi_adaptors
deba@1842
   304
  ///
deba@1842
   305
  /// \brief Graph using a node set of another graph and an
klao@1909
   306
  /// own uedge set.
deba@1842
   307
  ///
deba@1842
   308
  /// This structure can be used to establish another graph over a node set
deba@1842
   309
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   310
  /// original graph.
deba@1842
   311
  ///
deba@1842
   312
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   313
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   314
  /// "StaticGraph" concept.
deba@1842
   315
  ///
deba@1842
   316
  /// In the edge extension and removing it conforms to the 
deba@1962
   317
  /// \ref concept::ErasableUGraph "ErasableUGraph" concept.
deba@1842
   318
  template <typename _Graph>
deba@1979
   319
  class ListUEdgeSet 
deba@1979
   320
    : public UEdgeSetExtender<UGraphBaseExtender<ListEdgeSetBase<_Graph> > > {
deba@1842
   321
deba@1842
   322
  public:
deba@1842
   323
deba@1979
   324
    typedef UEdgeSetExtender<UGraphBaseExtender<
deba@1979
   325
      ListEdgeSetBase<_Graph> > > Parent;
deba@1842
   326
    
deba@1842
   327
    typedef typename Parent::Node Node;
deba@1842
   328
    typedef typename Parent::Edge Edge;
deba@1842
   329
    
deba@1842
   330
    typedef _Graph Graph;
deba@1842
   331
deba@1842
   332
deba@1842
   333
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   334
deba@1842
   335
    void eraseNode(const Node& node) {
deba@1842
   336
      Edge edge;
deba@1842
   337
      Parent::firstOut(edge, node);
deba@1842
   338
      while (edge != INVALID ) {
deba@1842
   339
	erase(edge);
deba@1842
   340
	Parent::firstOut(edge, node);
deba@1842
   341
      } 
deba@1842
   342
deba@1842
   343
    }
deba@1842
   344
    
deba@1842
   345
    void clearNodes() {
deba@1842
   346
      Parent::clear();
deba@1842
   347
    }
deba@1842
   348
deba@1842
   349
    class NodesImpl : public NodesImplBase {
deba@1842
   350
    public:
deba@1842
   351
      typedef NodesImplBase Parent;
deba@1842
   352
      
klao@1909
   353
      NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
deba@1842
   354
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   355
deba@1962
   356
      virtual ~NodesImpl() {}
deba@1842
   357
      
deba@1842
   358
    protected:
deba@1842
   359
deba@1842
   360
      virtual void erase(const Node& node) {
deba@1842
   361
	_edgeset.eraseNode(node);
deba@1842
   362
	Parent::erase(node);
deba@1842
   363
      }
deba@1866
   364
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   365
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1866
   366
	  _edgeset.eraseNode(nodes[i]);
deba@1866
   367
	}
deba@1866
   368
	Parent::erase(nodes);
deba@1866
   369
      }
deba@1842
   370
      virtual void clear() {
deba@1842
   371
	_edgeset.clearNodes();
deba@1842
   372
	Parent::clear();
deba@1842
   373
      }
deba@1842
   374
deba@1842
   375
    private:
klao@1909
   376
      ListUEdgeSet& _edgeset;
deba@1842
   377
    };
deba@1842
   378
deba@1842
   379
    NodesImpl nodes;
deba@1842
   380
    
deba@1842
   381
  public:
deba@1842
   382
deba@1842
   383
    /// \brief Constructor of the adaptor.
deba@1842
   384
    /// 
deba@1842
   385
    /// Constructor of the adaptor.
klao@1909
   386
    ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   387
      Parent::initalize(graph, nodes);
deba@1842
   388
    }
deba@1842
   389
    
deba@1842
   390
  };
deba@1842
   391
deba@1962
   392
  template <typename _Graph>
deba@1962
   393
  class SmartEdgeSetBase {
deba@1962
   394
  public:
deba@1962
   395
deba@1962
   396
    typedef _Graph Graph;
deba@1962
   397
    typedef typename Graph::Node Node;
deba@1962
   398
    typedef typename Graph::NodeIt NodeIt;
deba@1962
   399
deba@1962
   400
  protected:
deba@1962
   401
deba@1962
   402
    struct NodeT {
deba@1962
   403
      int first_out, first_in;
deba@1962
   404
      NodeT() : first_out(-1), first_in(-1) {}
deba@1962
   405
    };
deba@1962
   406
deba@1962
   407
    typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
deba@1962
   408
deba@1962
   409
    NodesImplBase* nodes;
deba@1962
   410
deba@1962
   411
    struct EdgeT {
deba@1962
   412
      Node source, target;
deba@1962
   413
      int next_out, next_in;
deba@1962
   414
      EdgeT() {}
deba@1962
   415
    };
deba@1962
   416
deba@1962
   417
    std::vector<EdgeT> edges;
deba@1962
   418
deba@1962
   419
    const Graph* graph;
deba@1962
   420
deba@1962
   421
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1962
   422
      graph = &_graph;
deba@1962
   423
      nodes = &_nodes;
deba@1962
   424
    }
deba@1962
   425
    
deba@1962
   426
  public:
deba@1962
   427
deba@1962
   428
    class Edge {
deba@1962
   429
      friend class SmartEdgeSetBase<Graph>;
deba@1962
   430
    protected:
deba@1962
   431
      Edge(int _id) : id(_id) {}
deba@1962
   432
      int id;
deba@1962
   433
    public:
deba@1962
   434
      Edge() {}
deba@1962
   435
      Edge(Invalid) : id(-1) {}
deba@1962
   436
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1962
   437
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1962
   438
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1962
   439
    };
deba@1962
   440
deba@1962
   441
    SmartEdgeSetBase() {} 
deba@1962
   442
deba@1962
   443
    Edge addEdge(const Node& source, const Node& target) {
deba@1962
   444
      int n = edges.size();
deba@1962
   445
      edges.push_back(EdgeT());
deba@1962
   446
      edges[n].next_in = (*nodes)[target].first_in;
deba@1962
   447
      (*nodes)[target].first_in = n;
deba@1962
   448
      edges[n].next_out = (*nodes)[source].first_out;
deba@1962
   449
      (*nodes)[source].first_out = n;
deba@1962
   450
      edges[n].source = source;
deba@1962
   451
      edges[n].target = target;
deba@1962
   452
      return Edge(n);
deba@1962
   453
    }
deba@1962
   454
deba@1962
   455
    void clear() {
deba@1962
   456
      Node node;
deba@1962
   457
      for (first(node); node != INVALID; next(node)) {
deba@1962
   458
        (*nodes)[node].first_in = -1;
deba@1962
   459
        (*nodes)[node].first_out = -1;
deba@1962
   460
      }
deba@1962
   461
      edges.clear();
deba@1962
   462
    }
deba@1962
   463
deba@1962
   464
    void first(Node& node) const {
deba@1962
   465
      graph->first(node);
deba@1962
   466
    }
deba@1962
   467
deba@1962
   468
    void next(Node& node) const {
deba@1962
   469
      graph->next(node);
deba@1962
   470
    }
deba@1962
   471
deba@1962
   472
    void first(Edge& edge) const {
deba@1962
   473
      edge.id = edges.size() - 1;
deba@1962
   474
    }
deba@1962
   475
deba@1962
   476
    void next(Edge& edge) const {
deba@1962
   477
      --edge.id;
deba@1962
   478
    }
deba@1962
   479
deba@1962
   480
    void firstOut(Edge& edge, const Node& node) const {
deba@1962
   481
      edge.id = (*nodes)[node].first_out;    
deba@1962
   482
    }
deba@1962
   483
    
deba@1962
   484
    void nextOut(Edge& edge) const {
deba@1962
   485
      edge.id = edges[edge.id].next_out;        
deba@1962
   486
    }
deba@1962
   487
deba@1962
   488
    void firstIn(Edge& edge, const Node& node) const {
deba@1962
   489
      edge.id = (*nodes)[node].first_in;          
deba@1962
   490
    }
deba@1962
   491
deba@1962
   492
    void nextIn(Edge& edge) const {
deba@1962
   493
      edge.id = edges[edge.id].next_in;    
deba@1962
   494
    }
deba@1962
   495
deba@1962
   496
    int id(const Node& node) const { return graph->id(node); }
deba@1962
   497
    int id(const Edge& edge) const { return edge.id; }
deba@1962
   498
deba@1962
   499
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@1962
   500
    Edge edgeFromId(int id) const { return Edge(id); }
deba@1962
   501
deba@1962
   502
    int maxNodeId() const { return graph->maxNodeId(); };
deba@1962
   503
    int maxEdgeId() const { return edges.size() - 1; }
deba@1962
   504
deba@1962
   505
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1962
   506
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1962
   507
deba@1962
   508
    template <typename _Value>
deba@1962
   509
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1962
   510
    public:
deba@1962
   511
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@1962
   512
      explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset) 
deba@1962
   513
	: Parent(*edgeset.graph) { }
deba@1962
   514
      NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1962
   515
	: Parent(*edgeset.graph, value) { }
deba@1962
   516
    };
deba@1962
   517
deba@1962
   518
  };
deba@1962
   519
deba@1962
   520
deba@1962
   521
  /// \ingroup semi_adaptors
deba@1962
   522
  ///
deba@1962
   523
  /// \brief Graph using a node set of another graph and an
deba@1962
   524
  /// own edge set.
deba@1962
   525
  ///
deba@1962
   526
  /// This structure can be used to establish another graph over a node set
deba@1962
   527
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   528
  /// original graph.
deba@1962
   529
  ///
deba@1962
   530
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   531
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   532
  /// "StaticGraph" concept.
deba@1962
   533
  ///
deba@1962
   534
  /// In the edge extension and removing it conforms to the 
deba@1962
   535
  /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
deba@1962
   536
  template <typename _Graph>
deba@1979
   537
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
deba@1962
   538
deba@1962
   539
  public:
deba@1962
   540
deba@1979
   541
    typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
deba@1962
   542
    
deba@1962
   543
    typedef typename Parent::Node Node;
deba@1962
   544
    typedef typename Parent::Edge Edge;
deba@1962
   545
    
deba@1962
   546
    typedef _Graph Graph;
deba@1962
   547
deba@1962
   548
    class UnsupportedOperation : public LogicError {
deba@1962
   549
    public:
deba@1962
   550
      virtual const char* exceptionName() const {
deba@1962
   551
        return "lemon::SmartEdgeSet::UnsupportedOperation";
deba@1962
   552
      }
deba@1962
   553
    };
deba@1962
   554
    
deba@1962
   555
deba@1962
   556
deba@1962
   557
  protected:
deba@1962
   558
deba@1962
   559
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   560
deba@1962
   561
    void eraseNode(const Node&) {
deba@1962
   562
      throw UnsupportedOperation();
deba@1962
   563
    }
deba@1962
   564
    
deba@1962
   565
    void clearNodes() {
deba@1962
   566
      Parent::clear();
deba@1962
   567
    }
deba@1962
   568
deba@1962
   569
    class NodesImpl : public NodesImplBase {
deba@1962
   570
    public:
deba@1962
   571
      typedef NodesImplBase Parent;
deba@1962
   572
      
deba@1962
   573
      NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
deba@1962
   574
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   575
deba@1962
   576
      virtual ~NodesImpl() {}
deba@1962
   577
      
deba@1962
   578
    protected:
deba@1962
   579
deba@1962
   580
      virtual void erase(const Node& node) {
deba@1962
   581
	_edgeset.eraseNode(node);
deba@1962
   582
	Parent::erase(node);
deba@1962
   583
      }
deba@1962
   584
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   585
        for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   586
          _edgeset.eraseNode(nodes[i]);
deba@1962
   587
        }
deba@1962
   588
	Parent::erase(nodes);
deba@1962
   589
      }
deba@1962
   590
      virtual void clear() {
deba@1962
   591
	_edgeset.clearNodes();
deba@1962
   592
	Parent::clear();
deba@1962
   593
      }
deba@1962
   594
deba@1962
   595
    private:
deba@1962
   596
      SmartEdgeSet& _edgeset;
deba@1962
   597
    };
deba@1962
   598
deba@1962
   599
    NodesImpl nodes;
deba@1962
   600
    
deba@1962
   601
  public:
deba@1962
   602
deba@1962
   603
    /// \brief Constructor of the adaptor.
deba@1962
   604
    /// 
deba@1962
   605
    /// Constructor of the adaptor.
deba@1962
   606
    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   607
      Parent::initalize(graph, nodes);
deba@1962
   608
    }
deba@1962
   609
    
deba@1962
   610
  };
deba@1962
   611
deba@1962
   612
  /// \ingroup semi_adaptors
deba@1962
   613
  ///
deba@1962
   614
  /// \brief Graph using a node set of another graph and an
deba@1962
   615
  /// own uedge set.
deba@1962
   616
  ///
deba@1962
   617
  /// This structure can be used to establish another graph over a node set
deba@1962
   618
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   619
  /// original graph.
deba@1962
   620
  ///
deba@1962
   621
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   622
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   623
  /// "StaticGraph" concept.
deba@1962
   624
  ///
deba@1962
   625
  /// In the edge extension and removing it conforms to the 
deba@1962
   626
  /// \ref concept::ExtendableUGraph "ExtendableUGraph" concept.
deba@1962
   627
  template <typename _Graph>
deba@1979
   628
  class SmartUEdgeSet 
deba@1979
   629
    : public UEdgeSetExtender<UGraphBaseExtender<SmartEdgeSetBase<_Graph> > > {
deba@1962
   630
deba@1962
   631
  public:
deba@1962
   632
deba@1979
   633
    typedef UEdgeSetExtender<UGraphBaseExtender<
deba@1979
   634
      SmartEdgeSetBase<_Graph> > > Parent;
deba@1962
   635
    
deba@1962
   636
    typedef typename Parent::Node Node;
deba@1962
   637
    typedef typename Parent::Edge Edge;
deba@1962
   638
    
deba@1962
   639
    typedef _Graph Graph;
deba@1962
   640
deba@1962
   641
    class UnsupportedOperation : public LogicError {
deba@1962
   642
    public:
deba@1962
   643
      virtual const char* exceptionName() const {
deba@1962
   644
        return "lemon::SmartUEdgeSet::UnsupportedOperation";
deba@1962
   645
      }
deba@1962
   646
    };
deba@1962
   647
deba@1962
   648
  protected:
deba@1962
   649
deba@1962
   650
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   651
deba@1962
   652
    void eraseNode(const Node&) {
deba@1962
   653
      throw UnsupportedOperation();
deba@1962
   654
    }
deba@1962
   655
    
deba@1962
   656
    void clearNodes() {
deba@1962
   657
      Parent::clear();
deba@1962
   658
    }
deba@1962
   659
deba@1962
   660
    class NodesImpl : public NodesImplBase {
deba@1962
   661
    public:
deba@1962
   662
      typedef NodesImplBase Parent;
deba@1962
   663
      
deba@1962
   664
      NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
deba@1962
   665
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   666
deba@1962
   667
      virtual ~NodesImpl() {}
deba@1962
   668
      
deba@1962
   669
    protected:
deba@1962
   670
deba@1962
   671
      virtual void erase(const Node& node) {
deba@1962
   672
	_edgeset.eraseNode(node);
deba@1962
   673
	Parent::erase(node);
deba@1962
   674
      }
deba@1962
   675
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   676
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   677
	  _edgeset.eraseNode(nodes[i]);
deba@1962
   678
	}
deba@1962
   679
	Parent::erase(nodes);
deba@1962
   680
      }
deba@1962
   681
      virtual void clear() {
deba@1962
   682
	_edgeset.clearNodes();
deba@1962
   683
	Parent::clear();
deba@1962
   684
      }
deba@1962
   685
deba@1962
   686
    private:
deba@1962
   687
      SmartUEdgeSet& _edgeset;
deba@1962
   688
    };
deba@1962
   689
deba@1962
   690
    NodesImpl nodes;
deba@1962
   691
    
deba@1962
   692
  public:
deba@1962
   693
deba@1962
   694
    /// \brief Constructor of the adaptor.
deba@1962
   695
    /// 
deba@1962
   696
    /// Constructor of the adaptor.
deba@1962
   697
    SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   698
      Parent::initalize(graph, nodes);
deba@1962
   699
    }
deba@1962
   700
    
deba@1962
   701
  };
deba@1962
   702
deba@1842
   703
}
deba@1842
   704
deba@1842
   705
#endif