lemon/edge_set.h
author Alpar Juttner <alpar@cs.elte.hu>
Wed, 12 Sep 2012 17:29:50 +0200
branch1.2
changeset 1154 2da3de1c0ebe
parent 834 c2230649a493
child 1270 dceba191c00d
permissions -rw-r--r--
Merge bugfix #448 to branch 1.2
deba@491
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@491
     2
 *
deba@491
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@491
     4
 *
alpar@956
     5
 * Copyright (C) 2003-2010
deba@491
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@491
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@491
     8
 *
deba@491
     9
 * Permission to use, modify and distribute this software is granted
deba@491
    10
 * provided that this copyright notice appears in all copies. For
deba@491
    11
 * precise terms see the accompanying LICENSE file.
deba@491
    12
 *
deba@491
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@491
    14
 * express or implied, and with no claim as to its suitability for any
deba@491
    15
 * purpose.
deba@491
    16
 *
deba@491
    17
 */
deba@491
    18
deba@491
    19
#ifndef LEMON_EDGE_SET_H
deba@491
    20
#define LEMON_EDGE_SET_H
deba@491
    21
deba@491
    22
#include <lemon/core.h>
deba@491
    23
#include <lemon/bits/edge_set_extender.h>
deba@491
    24
kpeter@707
    25
/// \ingroup graphs
deba@491
    26
/// \file
deba@491
    27
/// \brief ArcSet and EdgeSet classes.
deba@491
    28
///
deba@491
    29
/// Graphs which use another graph's node-set as own.
deba@491
    30
namespace lemon {
deba@491
    31
deba@559
    32
  template <typename GR>
deba@491
    33
  class ListArcSetBase {
deba@491
    34
  public:
deba@491
    35
deba@559
    36
    typedef typename GR::Node Node;
deba@559
    37
    typedef typename GR::NodeIt NodeIt;
deba@491
    38
deba@491
    39
  protected:
deba@491
    40
deba@491
    41
    struct NodeT {
deba@491
    42
      int first_out, first_in;
deba@491
    43
      NodeT() : first_out(-1), first_in(-1) {}
deba@491
    44
    };
deba@491
    45
deba@559
    46
    typedef typename ItemSetTraits<GR, Node>::
deba@491
    47
    template Map<NodeT>::Type NodesImplBase;
deba@491
    48
deba@559
    49
    NodesImplBase* _nodes;
deba@491
    50
deba@491
    51
    struct ArcT {
deba@491
    52
      Node source, target;
deba@491
    53
      int next_out, next_in;
deba@491
    54
      int prev_out, prev_in;
deba@491
    55
      ArcT() : prev_out(-1), prev_in(-1) {}
deba@491
    56
    };
deba@491
    57
deba@491
    58
    std::vector<ArcT> arcs;
deba@491
    59
deba@491
    60
    int first_arc;
deba@491
    61
    int first_free_arc;
deba@491
    62
deba@559
    63
    const GR* _graph;
deba@491
    64
deba@559
    65
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
    66
      _graph = &graph;
deba@559
    67
      _nodes = &nodes;
deba@491
    68
    }
deba@491
    69
deba@491
    70
  public:
deba@491
    71
deba@491
    72
    class Arc {
deba@559
    73
      friend class ListArcSetBase<GR>;
deba@491
    74
    protected:
deba@491
    75
      Arc(int _id) : id(_id) {}
deba@491
    76
      int id;
deba@491
    77
    public:
deba@491
    78
      Arc() {}
deba@491
    79
      Arc(Invalid) : id(-1) {}
deba@491
    80
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@491
    81
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@491
    82
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@491
    83
    };
deba@491
    84
deba@491
    85
    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
deba@491
    86
kpeter@717
    87
    Node addNode() {
kpeter@717
    88
      LEMON_ASSERT(false,
kpeter@717
    89
        "This graph structure does not support node insertion");
kpeter@717
    90
      return INVALID; // avoid warning
kpeter@717
    91
    }
kpeter@717
    92
deba@491
    93
    Arc addArc(const Node& u, const Node& v) {
deba@491
    94
      int n;
deba@491
    95
      if (first_free_arc == -1) {
deba@491
    96
        n = arcs.size();
deba@491
    97
        arcs.push_back(ArcT());
deba@491
    98
      } else {
deba@491
    99
        n = first_free_arc;
deba@491
   100
        first_free_arc = arcs[first_free_arc].next_in;
deba@491
   101
      }
deba@559
   102
      arcs[n].next_in = (*_nodes)[v].first_in;
deba@559
   103
      if ((*_nodes)[v].first_in != -1) {
deba@559
   104
        arcs[(*_nodes)[v].first_in].prev_in = n;
deba@491
   105
      }
deba@559
   106
      (*_nodes)[v].first_in = n;
deba@559
   107
      arcs[n].next_out = (*_nodes)[u].first_out;
deba@559
   108
      if ((*_nodes)[u].first_out != -1) {
deba@559
   109
        arcs[(*_nodes)[u].first_out].prev_out = n;
deba@491
   110
      }
deba@559
   111
      (*_nodes)[u].first_out = n;
deba@491
   112
      arcs[n].source = u;
deba@491
   113
      arcs[n].target = v;
deba@491
   114
      return Arc(n);
deba@491
   115
    }
deba@491
   116
deba@491
   117
    void erase(const Arc& arc) {
deba@491
   118
      int n = arc.id;
deba@491
   119
      if (arcs[n].prev_in != -1) {
deba@491
   120
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
deba@491
   121
      } else {
deba@559
   122
        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
deba@491
   123
      }
deba@491
   124
      if (arcs[n].next_in != -1) {
deba@491
   125
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
deba@491
   126
      }
deba@491
   127
deba@491
   128
      if (arcs[n].prev_out != -1) {
deba@491
   129
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@491
   130
      } else {
deba@559
   131
        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
deba@491
   132
      }
deba@491
   133
      if (arcs[n].next_out != -1) {
deba@491
   134
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
deba@491
   135
      }
deba@491
   136
deba@491
   137
    }
deba@491
   138
deba@491
   139
    void clear() {
deba@491
   140
      Node node;
deba@491
   141
      for (first(node); node != INVALID; next(node)) {
deba@559
   142
        (*_nodes)[node].first_in = -1;
deba@559
   143
        (*_nodes)[node].first_out = -1;
deba@491
   144
      }
deba@491
   145
      arcs.clear();
deba@491
   146
      first_arc = -1;
deba@491
   147
      first_free_arc = -1;
deba@491
   148
    }
deba@491
   149
deba@491
   150
    void first(Node& node) const {
deba@559
   151
      _graph->first(node);
deba@491
   152
    }
deba@491
   153
deba@491
   154
    void next(Node& node) const {
deba@559
   155
      _graph->next(node);
deba@491
   156
    }
deba@491
   157
deba@491
   158
    void first(Arc& arc) const {
deba@491
   159
      Node node;
deba@491
   160
      first(node);
deba@559
   161
      while (node != INVALID && (*_nodes)[node].first_in == -1) {
deba@491
   162
        next(node);
deba@491
   163
      }
deba@559
   164
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
deba@491
   165
    }
deba@491
   166
deba@491
   167
    void next(Arc& arc) const {
deba@491
   168
      if (arcs[arc.id].next_in != -1) {
deba@491
   169
        arc.id = arcs[arc.id].next_in;
deba@491
   170
      } else {
deba@491
   171
        Node node = arcs[arc.id].target;
deba@491
   172
        next(node);
deba@559
   173
        while (node != INVALID && (*_nodes)[node].first_in == -1) {
deba@491
   174
          next(node);
deba@491
   175
        }
deba@559
   176
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
deba@491
   177
      }
deba@491
   178
    }
deba@491
   179
deba@491
   180
    void firstOut(Arc& arc, const Node& node) const {
deba@559
   181
      arc.id = (*_nodes)[node].first_out;
deba@491
   182
    }
deba@491
   183
deba@491
   184
    void nextOut(Arc& arc) const {
deba@491
   185
      arc.id = arcs[arc.id].next_out;
deba@491
   186
    }
deba@491
   187
deba@491
   188
    void firstIn(Arc& arc, const Node& node) const {
deba@559
   189
      arc.id = (*_nodes)[node].first_in;
deba@491
   190
    }
deba@491
   191
deba@491
   192
    void nextIn(Arc& arc) const {
deba@491
   193
      arc.id = arcs[arc.id].next_in;
deba@491
   194
    }
deba@491
   195
deba@559
   196
    int id(const Node& node) const { return _graph->id(node); }
deba@491
   197
    int id(const Arc& arc) const { return arc.id; }
deba@491
   198
deba@559
   199
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
deba@491
   200
    Arc arcFromId(int ix) const { return Arc(ix); }
deba@491
   201
deba@559
   202
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
   203
    int maxArcId() const { return arcs.size() - 1; }
deba@491
   204
deba@491
   205
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
deba@491
   206
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
deba@491
   207
deba@559
   208
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
   209
deba@491
   210
    NodeNotifier& notifier(Node) const {
deba@559
   211
      return _graph->notifier(Node());
deba@491
   212
    }
deba@491
   213
deba@559
   214
    template <typename V>
deba@559
   215
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
   216
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
   217
deba@491
   218
    public:
deba@491
   219
deba@559
   220
      explicit NodeMap(const ListArcSetBase<GR>& arcset)
deba@559
   221
        : Parent(*arcset._graph) {}
deba@491
   222
deba@559
   223
      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
deba@559
   224
        : Parent(*arcset._graph, value) {}
deba@491
   225
deba@491
   226
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
   227
        return operator=<NodeMap>(cmap);
deba@491
   228
      }
deba@491
   229
deba@491
   230
      template <typename CMap>
deba@491
   231
      NodeMap& operator=(const CMap& cmap) {
deba@491
   232
        Parent::operator=(cmap);
deba@491
   233
        return *this;
deba@491
   234
      }
deba@491
   235
    };
deba@491
   236
deba@491
   237
  };
deba@491
   238
kpeter@707
   239
  /// \ingroup graphs
deba@491
   240
  ///
deba@491
   241
  /// \brief Digraph using a node set of another digraph or graph and
deba@491
   242
  /// an own arc set.
deba@491
   243
  ///
deba@491
   244
  /// This structure can be used to establish another directed graph
deba@491
   245
  /// over a node set of an existing one. This class uses the same
deba@491
   246
  /// Node type as the underlying graph, and each valid node of the
deba@491
   247
  /// original graph is valid in this arc set, therefore the node
deba@491
   248
  /// objects of the original graph can be used directly with this
deba@491
   249
  /// class. The node handling functions (id handling, observing, and
deba@491
   250
  /// iterators) works equivalently as in the original graph.
deba@491
   251
  ///
deba@491
   252
  /// This implementation is based on doubly-linked lists, from each
deba@491
   253
  /// node the outgoing and the incoming arcs make up lists, therefore
deba@491
   254
  /// one arc can be erased in constant time. It also makes possible,
deba@491
   255
  /// that node can be removed from the underlying graph, in this case
deba@491
   256
  /// all arcs incident to the given node is erased from the arc set.
deba@491
   257
  ///
kpeter@834
   258
  /// This class fully conforms to the \ref concepts::Digraph
kpeter@834
   259
  /// "Digraph" concept.
kpeter@834
   260
  /// It provides only linear time counting for nodes and arcs.
kpeter@834
   261
  ///
deba@559
   262
  /// \param GR The type of the graph which shares its node set with
deba@491
   263
  /// this class. Its interface must conform to the
deba@491
   264
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
   265
  /// concept.
deba@559
   266
  template <typename GR>
deba@559
   267
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
kpeter@664
   268
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
deba@491
   269
deba@491
   270
  public:
deba@491
   271
deba@491
   272
    typedef typename Parent::Node Node;
deba@491
   273
    typedef typename Parent::Arc Arc;
deba@491
   274
deba@491
   275
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
   276
deba@491
   277
    void eraseNode(const Node& node) {
deba@491
   278
      Arc arc;
deba@491
   279
      Parent::firstOut(arc, node);
deba@491
   280
      while (arc != INVALID ) {
deba@491
   281
        erase(arc);
deba@491
   282
        Parent::firstOut(arc, node);
deba@491
   283
      }
deba@491
   284
deba@491
   285
      Parent::firstIn(arc, node);
deba@491
   286
      while (arc != INVALID ) {
deba@491
   287
        erase(arc);
deba@491
   288
        Parent::firstIn(arc, node);
deba@491
   289
      }
deba@491
   290
    }
deba@491
   291
deba@491
   292
    void clearNodes() {
deba@491
   293
      Parent::clear();
deba@491
   294
    }
deba@491
   295
deba@491
   296
    class NodesImpl : public NodesImplBase {
deba@491
   297
      typedef NodesImplBase Parent;
deba@491
   298
kpeter@664
   299
    public:
deba@559
   300
      NodesImpl(const GR& graph, ListArcSet& arcset)
deba@491
   301
        : Parent(graph), _arcset(arcset) {}
deba@491
   302
deba@491
   303
      virtual ~NodesImpl() {}
deba@491
   304
deba@491
   305
    protected:
deba@491
   306
deba@491
   307
      virtual void erase(const Node& node) {
deba@491
   308
        _arcset.eraseNode(node);
deba@491
   309
        Parent::erase(node);
deba@491
   310
      }
deba@491
   311
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
   312
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
   313
          _arcset.eraseNode(nodes[i]);
deba@491
   314
        }
deba@491
   315
        Parent::erase(nodes);
deba@491
   316
      }
deba@491
   317
      virtual void clear() {
deba@491
   318
        _arcset.clearNodes();
deba@491
   319
        Parent::clear();
deba@491
   320
      }
deba@491
   321
deba@491
   322
    private:
deba@491
   323
      ListArcSet& _arcset;
deba@491
   324
    };
deba@491
   325
deba@559
   326
    NodesImpl _nodes;
deba@491
   327
deba@491
   328
  public:
deba@491
   329
deba@491
   330
    /// \brief Constructor of the ArcSet.
deba@491
   331
    ///
deba@491
   332
    /// Constructor of the ArcSet.
deba@559
   333
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
deba@559
   334
      Parent::initalize(graph, _nodes);
deba@491
   335
    }
deba@491
   336
deba@491
   337
    /// \brief Add a new arc to the digraph.
deba@491
   338
    ///
deba@491
   339
    /// Add a new arc to the digraph with source node \c s
deba@491
   340
    /// and target node \c t.
kpeter@606
   341
    /// \return The new arc.
deba@491
   342
    Arc addArc(const Node& s, const Node& t) {
deba@491
   343
      return Parent::addArc(s, t);
deba@491
   344
    }
deba@491
   345
deba@491
   346
    /// \brief Erase an arc from the digraph.
deba@491
   347
    ///
deba@491
   348
    /// Erase an arc \c a from the digraph.
deba@491
   349
    void erase(const Arc& a) {
deba@491
   350
      return Parent::erase(a);
deba@491
   351
    }
deba@491
   352
deba@491
   353
  };
deba@491
   354
deba@559
   355
  template <typename GR>
deba@491
   356
  class ListEdgeSetBase {
deba@491
   357
  public:
deba@491
   358
deba@559
   359
    typedef typename GR::Node Node;
deba@559
   360
    typedef typename GR::NodeIt NodeIt;
deba@491
   361
deba@491
   362
  protected:
deba@491
   363
deba@491
   364
    struct NodeT {
deba@491
   365
      int first_out;
deba@491
   366
      NodeT() : first_out(-1) {}
deba@491
   367
    };
deba@491
   368
deba@559
   369
    typedef typename ItemSetTraits<GR, Node>::
deba@491
   370
    template Map<NodeT>::Type NodesImplBase;
deba@491
   371
deba@559
   372
    NodesImplBase* _nodes;
deba@491
   373
deba@491
   374
    struct ArcT {
deba@491
   375
      Node target;
deba@491
   376
      int prev_out, next_out;
deba@491
   377
      ArcT() : prev_out(-1), next_out(-1) {}
deba@491
   378
    };
deba@491
   379
deba@491
   380
    std::vector<ArcT> arcs;
deba@491
   381
deba@491
   382
    int first_arc;
deba@491
   383
    int first_free_arc;
deba@491
   384
deba@559
   385
    const GR* _graph;
deba@491
   386
deba@559
   387
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
   388
      _graph = &graph;
deba@559
   389
      _nodes = &nodes;
deba@491
   390
    }
deba@491
   391
deba@491
   392
  public:
deba@491
   393
deba@491
   394
    class Edge {
deba@491
   395
      friend class ListEdgeSetBase;
deba@491
   396
    protected:
deba@491
   397
deba@491
   398
      int id;
deba@491
   399
      explicit Edge(int _id) { id = _id;}
deba@491
   400
deba@491
   401
    public:
deba@491
   402
      Edge() {}
deba@491
   403
      Edge (Invalid) { id = -1; }
deba@491
   404
      bool operator==(const Edge& arc) const {return id == arc.id;}
deba@491
   405
      bool operator!=(const Edge& arc) const {return id != arc.id;}
deba@491
   406
      bool operator<(const Edge& arc) const {return id < arc.id;}
deba@491
   407
    };
deba@491
   408
deba@491
   409
    class Arc {
deba@491
   410
      friend class ListEdgeSetBase;
deba@491
   411
    protected:
deba@491
   412
      Arc(int _id) : id(_id) {}
deba@491
   413
      int id;
deba@491
   414
    public:
deba@491
   415
      operator Edge() const { return edgeFromId(id / 2); }
deba@491
   416
deba@491
   417
      Arc() {}
deba@491
   418
      Arc(Invalid) : id(-1) {}
deba@491
   419
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@491
   420
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@491
   421
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@491
   422
    };
deba@491
   423
deba@491
   424
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
deba@491
   425
kpeter@717
   426
    Node addNode() {
kpeter@717
   427
      LEMON_ASSERT(false,
kpeter@717
   428
        "This graph structure does not support node insertion");
kpeter@717
   429
      return INVALID; // avoid warning
kpeter@717
   430
    }
kpeter@717
   431
deba@491
   432
    Edge addEdge(const Node& u, const Node& v) {
deba@491
   433
      int n;
deba@491
   434
deba@491
   435
      if (first_free_arc == -1) {
deba@491
   436
        n = arcs.size();
deba@491
   437
        arcs.push_back(ArcT());
deba@491
   438
        arcs.push_back(ArcT());
deba@491
   439
      } else {
deba@491
   440
        n = first_free_arc;
deba@491
   441
        first_free_arc = arcs[n].next_out;
deba@491
   442
      }
deba@491
   443
deba@491
   444
      arcs[n].target = u;
deba@491
   445
      arcs[n | 1].target = v;
deba@491
   446
deba@559
   447
      arcs[n].next_out = (*_nodes)[v].first_out;
deba@559
   448
      if ((*_nodes)[v].first_out != -1) {
deba@559
   449
        arcs[(*_nodes)[v].first_out].prev_out = n;
deba@491
   450
      }
deba@559
   451
      (*_nodes)[v].first_out = n;
deba@491
   452
      arcs[n].prev_out = -1;
deba@491
   453
deba@559
   454
      if ((*_nodes)[u].first_out != -1) {
deba@559
   455
        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
deba@491
   456
      }
deba@559
   457
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
deba@559
   458
      (*_nodes)[u].first_out = (n | 1);
deba@491
   459
      arcs[n | 1].prev_out = -1;
deba@491
   460
deba@491
   461
      return Edge(n / 2);
deba@491
   462
    }
deba@491
   463
deba@491
   464
    void erase(const Edge& arc) {
deba@491
   465
      int n = arc.id * 2;
deba@491
   466
deba@491
   467
      if (arcs[n].next_out != -1) {
deba@491
   468
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
deba@491
   469
      }
deba@491
   470
deba@491
   471
      if (arcs[n].prev_out != -1) {
deba@491
   472
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@491
   473
      } else {
deba@559
   474
        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
deba@491
   475
      }
deba@491
   476
deba@491
   477
      if (arcs[n | 1].next_out != -1) {
deba@491
   478
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
deba@491
   479
      }
deba@491
   480
deba@491
   481
      if (arcs[n | 1].prev_out != -1) {
deba@491
   482
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
deba@491
   483
      } else {
deba@559
   484
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
deba@491
   485
      }
deba@491
   486
deba@491
   487
      arcs[n].next_out = first_free_arc;
deba@491
   488
      first_free_arc = n;
deba@491
   489
deba@491
   490
    }
deba@491
   491
deba@491
   492
    void clear() {
deba@491
   493
      Node node;
deba@491
   494
      for (first(node); node != INVALID; next(node)) {
deba@559
   495
        (*_nodes)[node].first_out = -1;
deba@491
   496
      }
deba@491
   497
      arcs.clear();
deba@491
   498
      first_arc = -1;
deba@491
   499
      first_free_arc = -1;
deba@491
   500
    }
deba@491
   501
deba@491
   502
    void first(Node& node) const {
deba@559
   503
      _graph->first(node);
deba@491
   504
    }
deba@491
   505
deba@491
   506
    void next(Node& node) const {
deba@559
   507
      _graph->next(node);
deba@491
   508
    }
deba@491
   509
deba@491
   510
    void first(Arc& arc) const {
deba@491
   511
      Node node;
deba@491
   512
      first(node);
deba@559
   513
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
deba@491
   514
        next(node);
deba@491
   515
      }
deba@559
   516
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
deba@491
   517
    }
deba@491
   518
deba@491
   519
    void next(Arc& arc) const {
deba@491
   520
      if (arcs[arc.id].next_out != -1) {
deba@491
   521
        arc.id = arcs[arc.id].next_out;
deba@491
   522
      } else {
deba@491
   523
        Node node = arcs[arc.id ^ 1].target;
deba@491
   524
        next(node);
deba@559
   525
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
deba@491
   526
          next(node);
deba@491
   527
        }
deba@559
   528
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
deba@491
   529
      }
deba@491
   530
    }
deba@491
   531
deba@491
   532
    void first(Edge& edge) const {
deba@491
   533
      Node node;
deba@491
   534
      first(node);
deba@491
   535
      while (node != INVALID) {
deba@559
   536
        edge.id = (*_nodes)[node].first_out;
deba@491
   537
        while ((edge.id & 1) != 1) {
deba@491
   538
          edge.id = arcs[edge.id].next_out;
deba@491
   539
        }
deba@491
   540
        if (edge.id != -1) {
deba@491
   541
          edge.id /= 2;
deba@491
   542
          return;
deba@491
   543
        }
deba@491
   544
        next(node);
deba@491
   545
      }
deba@491
   546
      edge.id = -1;
deba@491
   547
    }
deba@491
   548
deba@491
   549
    void next(Edge& edge) const {
deba@491
   550
      Node node = arcs[edge.id * 2].target;
deba@491
   551
      edge.id = arcs[(edge.id * 2) | 1].next_out;
deba@491
   552
      while ((edge.id & 1) != 1) {
deba@491
   553
        edge.id = arcs[edge.id].next_out;
deba@491
   554
      }
deba@491
   555
      if (edge.id != -1) {
deba@491
   556
        edge.id /= 2;
deba@491
   557
        return;
deba@491
   558
      }
deba@491
   559
      next(node);
deba@491
   560
      while (node != INVALID) {
deba@559
   561
        edge.id = (*_nodes)[node].first_out;
deba@491
   562
        while ((edge.id & 1) != 1) {
deba@491
   563
          edge.id = arcs[edge.id].next_out;
deba@491
   564
        }
deba@491
   565
        if (edge.id != -1) {
deba@491
   566
          edge.id /= 2;
deba@491
   567
          return;
deba@491
   568
        }
deba@491
   569
        next(node);
deba@491
   570
      }
deba@491
   571
      edge.id = -1;
deba@491
   572
    }
deba@491
   573
deba@491
   574
    void firstOut(Arc& arc, const Node& node) const {
deba@559
   575
      arc.id = (*_nodes)[node].first_out;
deba@491
   576
    }
deba@491
   577
deba@491
   578
    void nextOut(Arc& arc) const {
deba@491
   579
      arc.id = arcs[arc.id].next_out;
deba@491
   580
    }
deba@491
   581
deba@491
   582
    void firstIn(Arc& arc, const Node& node) const {
deba@559
   583
      arc.id = (((*_nodes)[node].first_out) ^ 1);
deba@491
   584
      if (arc.id == -2) arc.id = -1;
deba@491
   585
    }
deba@491
   586
deba@491
   587
    void nextIn(Arc& arc) const {
deba@491
   588
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
deba@491
   589
      if (arc.id == -2) arc.id = -1;
deba@491
   590
    }
deba@491
   591
deba@491
   592
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
deba@559
   593
      int de = (*_nodes)[node].first_out;
deba@491
   594
      if (de != -1 ) {
deba@491
   595
        arc.id = de / 2;
deba@491
   596
        dir = ((de & 1) == 1);
deba@491
   597
      } else {
deba@491
   598
        arc.id = -1;
deba@491
   599
        dir = true;
deba@491
   600
      }
deba@491
   601
    }
deba@491
   602
    void nextInc(Edge &arc, bool& dir) const {
deba@491
   603
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
deba@491
   604
      if (de != -1 ) {
deba@491
   605
        arc.id = de / 2;
deba@491
   606
        dir = ((de & 1) == 1);
deba@491
   607
      } else {
deba@491
   608
        arc.id = -1;
deba@491
   609
        dir = true;
deba@491
   610
      }
deba@491
   611
    }
deba@491
   612
deba@491
   613
    static bool direction(Arc arc) {
deba@491
   614
      return (arc.id & 1) == 1;
deba@491
   615
    }
deba@491
   616
deba@491
   617
    static Arc direct(Edge edge, bool dir) {
deba@491
   618
      return Arc(edge.id * 2 + (dir ? 1 : 0));
deba@491
   619
    }
deba@491
   620
deba@559
   621
    int id(const Node& node) const { return _graph->id(node); }
deba@491
   622
    static int id(Arc e) { return e.id; }
deba@491
   623
    static int id(Edge e) { return e.id; }
deba@491
   624
deba@559
   625
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
deba@491
   626
    static Arc arcFromId(int id) { return Arc(id);}
deba@491
   627
    static Edge edgeFromId(int id) { return Edge(id);}
deba@491
   628
deba@559
   629
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
   630
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@491
   631
    int maxArcId() const { return arcs.size()-1; }
deba@491
   632
deba@491
   633
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
deba@491
   634
    Node target(Arc e) const { return arcs[e.id].target; }
deba@491
   635
deba@491
   636
    Node u(Edge e) const { return arcs[2 * e.id].target; }
deba@491
   637
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
deba@491
   638
deba@559
   639
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
   640
deba@491
   641
    NodeNotifier& notifier(Node) const {
deba@559
   642
      return _graph->notifier(Node());
deba@491
   643
    }
deba@491
   644
deba@559
   645
    template <typename V>
deba@559
   646
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
   647
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
   648
deba@491
   649
    public:
deba@491
   650
deba@559
   651
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
deba@559
   652
        : Parent(*arcset._graph) {}
deba@491
   653
deba@559
   654
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
deba@559
   655
        : Parent(*arcset._graph, value) {}
deba@491
   656
deba@491
   657
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
   658
        return operator=<NodeMap>(cmap);
deba@491
   659
      }
deba@491
   660
deba@491
   661
      template <typename CMap>
deba@491
   662
      NodeMap& operator=(const CMap& cmap) {
deba@491
   663
        Parent::operator=(cmap);
deba@491
   664
        return *this;
deba@491
   665
      }
deba@491
   666
    };
deba@491
   667
deba@491
   668
  };
deba@491
   669
kpeter@707
   670
  /// \ingroup graphs
deba@491
   671
  ///
deba@491
   672
  /// \brief Graph using a node set of another digraph or graph and an
deba@491
   673
  /// own edge set.
deba@491
   674
  ///
deba@491
   675
  /// This structure can be used to establish another graph over a
deba@491
   676
  /// node set of an existing one. This class uses the same Node type
deba@491
   677
  /// as the underlying graph, and each valid node of the original
deba@491
   678
  /// graph is valid in this arc set, therefore the node objects of
deba@491
   679
  /// the original graph can be used directly with this class. The
deba@491
   680
  /// node handling functions (id handling, observing, and iterators)
deba@491
   681
  /// works equivalently as in the original graph.
deba@491
   682
  ///
deba@491
   683
  /// This implementation is based on doubly-linked lists, from each
deba@491
   684
  /// node the incident edges make up lists, therefore one edge can be
deba@491
   685
  /// erased in constant time. It also makes possible, that node can
deba@491
   686
  /// be removed from the underlying graph, in this case all edges
deba@491
   687
  /// incident to the given node is erased from the arc set.
deba@491
   688
  ///
kpeter@834
   689
  /// This class fully conforms to the \ref concepts::Graph "Graph"
kpeter@834
   690
  /// concept.
kpeter@834
   691
  /// It provides only linear time counting for nodes, edges and arcs.
kpeter@834
   692
  ///
deba@559
   693
  /// \param GR The type of the graph which shares its node set
deba@491
   694
  /// with this class. Its interface must conform to the
deba@491
   695
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
   696
  /// concept.
deba@559
   697
  template <typename GR>
deba@559
   698
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
kpeter@664
   699
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
deba@491
   700
deba@491
   701
  public:
deba@491
   702
deba@491
   703
    typedef typename Parent::Node Node;
deba@491
   704
    typedef typename Parent::Arc Arc;
deba@491
   705
    typedef typename Parent::Edge Edge;
deba@491
   706
deba@491
   707
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
   708
deba@491
   709
    void eraseNode(const Node& node) {
deba@491
   710
      Arc arc;
deba@491
   711
      Parent::firstOut(arc, node);
deba@491
   712
      while (arc != INVALID ) {
deba@491
   713
        erase(arc);
deba@491
   714
        Parent::firstOut(arc, node);
deba@491
   715
      }
deba@491
   716
deba@491
   717
    }
deba@491
   718
deba@491
   719
    void clearNodes() {
deba@491
   720
      Parent::clear();
deba@491
   721
    }
deba@491
   722
deba@491
   723
    class NodesImpl : public NodesImplBase {
deba@491
   724
      typedef NodesImplBase Parent;
deba@491
   725
kpeter@664
   726
    public:
deba@559
   727
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
deba@491
   728
        : Parent(graph), _arcset(arcset) {}
deba@491
   729
deba@491
   730
      virtual ~NodesImpl() {}
deba@491
   731
deba@491
   732
    protected:
deba@491
   733
deba@491
   734
      virtual void erase(const Node& node) {
deba@491
   735
        _arcset.eraseNode(node);
deba@491
   736
        Parent::erase(node);
deba@491
   737
      }
deba@491
   738
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
   739
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
   740
          _arcset.eraseNode(nodes[i]);
deba@491
   741
        }
deba@491
   742
        Parent::erase(nodes);
deba@491
   743
      }
deba@491
   744
      virtual void clear() {
deba@491
   745
        _arcset.clearNodes();
deba@491
   746
        Parent::clear();
deba@491
   747
      }
deba@491
   748
deba@491
   749
    private:
deba@491
   750
      ListEdgeSet& _arcset;
deba@491
   751
    };
deba@491
   752
deba@559
   753
    NodesImpl _nodes;
deba@491
   754
deba@491
   755
  public:
deba@491
   756
deba@491
   757
    /// \brief Constructor of the EdgeSet.
deba@491
   758
    ///
deba@491
   759
    /// Constructor of the EdgeSet.
deba@559
   760
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
deba@559
   761
      Parent::initalize(graph, _nodes);
deba@491
   762
    }
deba@491
   763
deba@491
   764
    /// \brief Add a new edge to the graph.
deba@491
   765
    ///
deba@491
   766
    /// Add a new edge to the graph with node \c u
deba@491
   767
    /// and node \c v endpoints.
kpeter@606
   768
    /// \return The new edge.
deba@491
   769
    Edge addEdge(const Node& u, const Node& v) {
deba@491
   770
      return Parent::addEdge(u, v);
deba@491
   771
    }
deba@491
   772
deba@491
   773
    /// \brief Erase an edge from the graph.
deba@491
   774
    ///
deba@491
   775
    /// Erase the edge \c e from the graph.
deba@491
   776
    void erase(const Edge& e) {
deba@491
   777
      return Parent::erase(e);
deba@491
   778
    }
deba@491
   779
deba@491
   780
  };
deba@491
   781
deba@559
   782
  template <typename GR>
deba@491
   783
  class SmartArcSetBase {
deba@491
   784
  public:
deba@491
   785
kpeter@664
   786
    typedef typename GR::Node Node;
kpeter@664
   787
    typedef typename GR::NodeIt NodeIt;
deba@491
   788
deba@491
   789
  protected:
deba@491
   790
deba@491
   791
    struct NodeT {
deba@491
   792
      int first_out, first_in;
deba@491
   793
      NodeT() : first_out(-1), first_in(-1) {}
deba@491
   794
    };
deba@491
   795
deba@559
   796
    typedef typename ItemSetTraits<GR, Node>::
deba@491
   797
    template Map<NodeT>::Type NodesImplBase;
deba@491
   798
deba@559
   799
    NodesImplBase* _nodes;
deba@491
   800
deba@491
   801
    struct ArcT {
deba@491
   802
      Node source, target;
deba@491
   803
      int next_out, next_in;
deba@491
   804
      ArcT() {}
deba@491
   805
    };
deba@491
   806
deba@491
   807
    std::vector<ArcT> arcs;
deba@491
   808
deba@559
   809
    const GR* _graph;
deba@491
   810
deba@559
   811
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
   812
      _graph = &graph;
deba@559
   813
      _nodes = &nodes;
deba@491
   814
    }
deba@491
   815
deba@491
   816
  public:
deba@491
   817
deba@491
   818
    class Arc {
deba@559
   819
      friend class SmartArcSetBase<GR>;
deba@491
   820
    protected:
deba@491
   821
      Arc(int _id) : id(_id) {}
deba@491
   822
      int id;
deba@491
   823
    public:
deba@491
   824
      Arc() {}
deba@491
   825
      Arc(Invalid) : id(-1) {}
deba@491
   826
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@491
   827
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@491
   828
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@491
   829
    };
deba@491
   830
deba@491
   831
    SmartArcSetBase() {}
deba@491
   832
kpeter@717
   833
    Node addNode() {
kpeter@717
   834
      LEMON_ASSERT(false,
kpeter@717
   835
        "This graph structure does not support node insertion");
kpeter@717
   836
      return INVALID; // avoid warning
kpeter@717
   837
    }
kpeter@717
   838
deba@491
   839
    Arc addArc(const Node& u, const Node& v) {
deba@491
   840
      int n = arcs.size();
deba@491
   841
      arcs.push_back(ArcT());
deba@559
   842
      arcs[n].next_in = (*_nodes)[v].first_in;
deba@559
   843
      (*_nodes)[v].first_in = n;
deba@559
   844
      arcs[n].next_out = (*_nodes)[u].first_out;
deba@559
   845
      (*_nodes)[u].first_out = n;
deba@491
   846
      arcs[n].source = u;
deba@491
   847
      arcs[n].target = v;
deba@491
   848
      return Arc(n);
deba@491
   849
    }
deba@491
   850
deba@491
   851
    void clear() {
deba@491
   852
      Node node;
deba@491
   853
      for (first(node); node != INVALID; next(node)) {
deba@559
   854
        (*_nodes)[node].first_in = -1;
deba@559
   855
        (*_nodes)[node].first_out = -1;
deba@491
   856
      }
deba@491
   857
      arcs.clear();
deba@491
   858
    }
deba@491
   859
deba@491
   860
    void first(Node& node) const {
deba@559
   861
      _graph->first(node);
deba@491
   862
    }
deba@491
   863
deba@491
   864
    void next(Node& node) const {
deba@559
   865
      _graph->next(node);
deba@491
   866
    }
deba@491
   867
deba@491
   868
    void first(Arc& arc) const {
deba@491
   869
      arc.id = arcs.size() - 1;
deba@491
   870
    }
deba@491
   871
kpeter@825
   872
    static void next(Arc& arc) {
deba@491
   873
      --arc.id;
deba@491
   874
    }
deba@491
   875
deba@491
   876
    void firstOut(Arc& arc, const Node& node) const {
deba@559
   877
      arc.id = (*_nodes)[node].first_out;
deba@491
   878
    }
deba@491
   879
deba@491
   880
    void nextOut(Arc& arc) const {
deba@491
   881
      arc.id = arcs[arc.id].next_out;
deba@491
   882
    }
deba@491
   883
deba@491
   884
    void firstIn(Arc& arc, const Node& node) const {
deba@559
   885
      arc.id = (*_nodes)[node].first_in;
deba@491
   886
    }
deba@491
   887
deba@491
   888
    void nextIn(Arc& arc) const {
deba@491
   889
      arc.id = arcs[arc.id].next_in;
deba@491
   890
    }
deba@491
   891
deba@559
   892
    int id(const Node& node) const { return _graph->id(node); }
deba@491
   893
    int id(const Arc& arc) const { return arc.id; }
deba@491
   894
deba@559
   895
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
deba@491
   896
    Arc arcFromId(int ix) const { return Arc(ix); }
deba@491
   897
deba@559
   898
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
   899
    int maxArcId() const { return arcs.size() - 1; }
deba@491
   900
deba@491
   901
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
deba@491
   902
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
deba@491
   903
deba@559
   904
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
   905
deba@491
   906
    NodeNotifier& notifier(Node) const {
deba@559
   907
      return _graph->notifier(Node());
deba@491
   908
    }
deba@491
   909
deba@559
   910
    template <typename V>
deba@559
   911
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
   912
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
   913
deba@491
   914
    public:
deba@491
   915
deba@559
   916
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
deba@559
   917
        : Parent(*arcset._graph) { }
deba@491
   918
deba@559
   919
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
deba@559
   920
        : Parent(*arcset._graph, value) { }
deba@491
   921
deba@491
   922
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
   923
        return operator=<NodeMap>(cmap);
deba@491
   924
      }
deba@491
   925
deba@491
   926
      template <typename CMap>
deba@491
   927
      NodeMap& operator=(const CMap& cmap) {
deba@491
   928
        Parent::operator=(cmap);
deba@491
   929
        return *this;
deba@491
   930
      }
deba@491
   931
    };
deba@491
   932
deba@491
   933
  };
deba@491
   934
deba@491
   935
kpeter@707
   936
  /// \ingroup graphs
deba@491
   937
  ///
deba@491
   938
  /// \brief Digraph using a node set of another digraph or graph and
deba@491
   939
  /// an own arc set.
deba@491
   940
  ///
deba@491
   941
  /// This structure can be used to establish another directed graph
deba@491
   942
  /// over a node set of an existing one. This class uses the same
deba@491
   943
  /// Node type as the underlying graph, and each valid node of the
deba@491
   944
  /// original graph is valid in this arc set, therefore the node
deba@491
   945
  /// objects of the original graph can be used directly with this
deba@491
   946
  /// class. The node handling functions (id handling, observing, and
deba@491
   947
  /// iterators) works equivalently as in the original graph.
deba@491
   948
  ///
deba@559
   949
  /// \param GR The type of the graph which shares its node set with
deba@491
   950
  /// this class. Its interface must conform to the
deba@491
   951
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
   952
  /// concept.
deba@491
   953
  ///
deba@491
   954
  /// This implementation is slightly faster than the \c ListArcSet,
deba@491
   955
  /// because it uses continuous storage for arcs and it uses just
deba@491
   956
  /// single-linked lists for enumerate outgoing and incoming
deba@491
   957
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
deba@491
   958
  ///
kpeter@834
   959
  /// This class fully conforms to the \ref concepts::Digraph "Digraph"
kpeter@834
   960
  /// concept.
kpeter@834
   961
  /// It provides only linear time counting for nodes and arcs.
kpeter@834
   962
  ///
deba@491
   963
  /// \warning If a node is erased from the underlying graph and this
deba@491
   964
  /// node is the source or target of one arc in the arc set, then
deba@491
   965
  /// the arc set is invalidated, and it cannot be used anymore. The
deba@491
   966
  /// validity can be checked with the \c valid() member function.
deba@559
   967
  template <typename GR>
deba@559
   968
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
kpeter@664
   969
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
deba@491
   970
deba@491
   971
  public:
deba@491
   972
deba@491
   973
    typedef typename Parent::Node Node;
deba@491
   974
    typedef typename Parent::Arc Arc;
deba@491
   975
deba@491
   976
  protected:
deba@491
   977
deba@491
   978
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
   979
deba@491
   980
    void eraseNode(const Node& node) {
deba@491
   981
      if (typename Parent::InArcIt(*this, node) == INVALID &&
deba@491
   982
          typename Parent::OutArcIt(*this, node) == INVALID) {
deba@491
   983
        return;
deba@491
   984
      }
deba@491
   985
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@491
   986
    }
deba@491
   987
deba@491
   988
    void clearNodes() {
deba@491
   989
      Parent::clear();
deba@491
   990
    }
deba@491
   991
deba@491
   992
    class NodesImpl : public NodesImplBase {
deba@491
   993
      typedef NodesImplBase Parent;
deba@491
   994
kpeter@664
   995
    public:
deba@559
   996
      NodesImpl(const GR& graph, SmartArcSet& arcset)
deba@491
   997
        : Parent(graph), _arcset(arcset) {}
deba@491
   998
deba@491
   999
      virtual ~NodesImpl() {}
deba@491
  1000
deba@491
  1001
      bool attached() const {
deba@491
  1002
        return Parent::attached();
deba@491
  1003
      }
deba@491
  1004
deba@491
  1005
    protected:
deba@491
  1006
deba@491
  1007
      virtual void erase(const Node& node) {
deba@491
  1008
        try {
deba@491
  1009
          _arcset.eraseNode(node);
deba@491
  1010
          Parent::erase(node);
deba@491
  1011
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1012
          Parent::clear();
deba@491
  1013
          throw;
deba@491
  1014
        }
deba@491
  1015
      }
deba@491
  1016
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
  1017
        try {
deba@491
  1018
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
  1019
            _arcset.eraseNode(nodes[i]);
deba@491
  1020
          }
deba@491
  1021
          Parent::erase(nodes);
deba@491
  1022
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1023
          Parent::clear();
deba@491
  1024
          throw;
deba@491
  1025
        }
deba@491
  1026
      }
deba@491
  1027
      virtual void clear() {
deba@491
  1028
        _arcset.clearNodes();
deba@491
  1029
        Parent::clear();
deba@491
  1030
      }
deba@491
  1031
deba@491
  1032
    private:
deba@491
  1033
      SmartArcSet& _arcset;
deba@491
  1034
    };
deba@491
  1035
deba@559
  1036
    NodesImpl _nodes;
deba@491
  1037
deba@491
  1038
  public:
deba@491
  1039
deba@491
  1040
    /// \brief Constructor of the ArcSet.
deba@491
  1041
    ///
deba@491
  1042
    /// Constructor of the ArcSet.
deba@559
  1043
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
deba@559
  1044
      Parent::initalize(graph, _nodes);
deba@491
  1045
    }
deba@491
  1046
deba@491
  1047
    /// \brief Add a new arc to the digraph.
deba@491
  1048
    ///
deba@491
  1049
    /// Add a new arc to the digraph with source node \c s
deba@491
  1050
    /// and target node \c t.
kpeter@606
  1051
    /// \return The new arc.
deba@491
  1052
    Arc addArc(const Node& s, const Node& t) {
deba@491
  1053
      return Parent::addArc(s, t);
deba@491
  1054
    }
deba@491
  1055
deba@491
  1056
    /// \brief Validity check
deba@491
  1057
    ///
deba@491
  1058
    /// This functions gives back false if the ArcSet is
deba@491
  1059
    /// invalidated. It occurs when a node in the underlying graph is
deba@491
  1060
    /// erased and it is not isolated in the ArcSet.
deba@491
  1061
    bool valid() const {
deba@559
  1062
      return _nodes.attached();
deba@491
  1063
    }
deba@491
  1064
deba@491
  1065
  };
deba@491
  1066
deba@491
  1067
deba@559
  1068
  template <typename GR>
deba@491
  1069
  class SmartEdgeSetBase {
deba@491
  1070
  public:
deba@491
  1071
deba@559
  1072
    typedef typename GR::Node Node;
deba@559
  1073
    typedef typename GR::NodeIt NodeIt;
deba@491
  1074
deba@491
  1075
  protected:
deba@491
  1076
deba@491
  1077
    struct NodeT {
deba@491
  1078
      int first_out;
deba@491
  1079
      NodeT() : first_out(-1) {}
deba@491
  1080
    };
deba@491
  1081
deba@559
  1082
    typedef typename ItemSetTraits<GR, Node>::
deba@491
  1083
    template Map<NodeT>::Type NodesImplBase;
deba@491
  1084
deba@559
  1085
    NodesImplBase* _nodes;
deba@491
  1086
deba@491
  1087
    struct ArcT {
deba@491
  1088
      Node target;
deba@491
  1089
      int next_out;
deba@491
  1090
      ArcT() {}
deba@491
  1091
    };
deba@491
  1092
deba@491
  1093
    std::vector<ArcT> arcs;
deba@491
  1094
deba@559
  1095
    const GR* _graph;
deba@491
  1096
deba@559
  1097
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
  1098
      _graph = &graph;
deba@559
  1099
      _nodes = &nodes;
deba@491
  1100
    }
deba@491
  1101
deba@491
  1102
  public:
deba@491
  1103
deba@491
  1104
    class Edge {
deba@491
  1105
      friend class SmartEdgeSetBase;
deba@491
  1106
    protected:
deba@491
  1107
deba@491
  1108
      int id;
deba@491
  1109
      explicit Edge(int _id) { id = _id;}
deba@491
  1110
deba@491
  1111
    public:
deba@491
  1112
      Edge() {}
deba@491
  1113
      Edge (Invalid) { id = -1; }
deba@491
  1114
      bool operator==(const Edge& arc) const {return id == arc.id;}
deba@491
  1115
      bool operator!=(const Edge& arc) const {return id != arc.id;}
deba@491
  1116
      bool operator<(const Edge& arc) const {return id < arc.id;}
deba@491
  1117
    };
deba@491
  1118
deba@491
  1119
    class Arc {
deba@491
  1120
      friend class SmartEdgeSetBase;
deba@491
  1121
    protected:
deba@491
  1122
      Arc(int _id) : id(_id) {}
deba@491
  1123
      int id;
deba@491
  1124
    public:
deba@491
  1125
      operator Edge() const { return edgeFromId(id / 2); }
deba@491
  1126
deba@491
  1127
      Arc() {}
deba@491
  1128
      Arc(Invalid) : id(-1) {}
deba@491
  1129
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@491
  1130
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@491
  1131
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@491
  1132
    };
deba@491
  1133
deba@491
  1134
    SmartEdgeSetBase() {}
deba@491
  1135
kpeter@717
  1136
    Node addNode() {
kpeter@717
  1137
      LEMON_ASSERT(false,
kpeter@717
  1138
        "This graph structure does not support node insertion");
kpeter@717
  1139
      return INVALID; // avoid warning
kpeter@717
  1140
    }
kpeter@717
  1141
deba@491
  1142
    Edge addEdge(const Node& u, const Node& v) {
deba@491
  1143
      int n = arcs.size();
deba@491
  1144
      arcs.push_back(ArcT());
deba@491
  1145
      arcs.push_back(ArcT());
deba@491
  1146
deba@491
  1147
      arcs[n].target = u;
deba@491
  1148
      arcs[n | 1].target = v;
deba@491
  1149
deba@559
  1150
      arcs[n].next_out = (*_nodes)[v].first_out;
deba@559
  1151
      (*_nodes)[v].first_out = n;
deba@491
  1152
deba@559
  1153
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
deba@559
  1154
      (*_nodes)[u].first_out = (n | 1);
deba@491
  1155
deba@491
  1156
      return Edge(n / 2);
deba@491
  1157
    }
deba@491
  1158
deba@491
  1159
    void clear() {
deba@491
  1160
      Node node;
deba@491
  1161
      for (first(node); node != INVALID; next(node)) {
deba@559
  1162
        (*_nodes)[node].first_out = -1;
deba@491
  1163
      }
deba@491
  1164
      arcs.clear();
deba@491
  1165
    }
deba@491
  1166
deba@491
  1167
    void first(Node& node) const {
deba@559
  1168
      _graph->first(node);
deba@491
  1169
    }
deba@491
  1170
deba@491
  1171
    void next(Node& node) const {
deba@559
  1172
      _graph->next(node);
deba@491
  1173
    }
deba@491
  1174
deba@491
  1175
    void first(Arc& arc) const {
deba@491
  1176
      arc.id = arcs.size() - 1;
deba@491
  1177
    }
deba@491
  1178
kpeter@825
  1179
    static void next(Arc& arc) {
deba@491
  1180
      --arc.id;
deba@491
  1181
    }
deba@491
  1182
deba@491
  1183
    void first(Edge& arc) const {
deba@491
  1184
      arc.id = arcs.size() / 2 - 1;
deba@491
  1185
    }
deba@491
  1186
kpeter@825
  1187
    static void next(Edge& arc) {
deba@491
  1188
      --arc.id;
deba@491
  1189
    }
deba@491
  1190
deba@491
  1191
    void firstOut(Arc& arc, const Node& node) const {
deba@559
  1192
      arc.id = (*_nodes)[node].first_out;
deba@491
  1193
    }
deba@491
  1194
deba@491
  1195
    void nextOut(Arc& arc) const {
deba@491
  1196
      arc.id = arcs[arc.id].next_out;
deba@491
  1197
    }
deba@491
  1198
deba@491
  1199
    void firstIn(Arc& arc, const Node& node) const {
deba@559
  1200
      arc.id = (((*_nodes)[node].first_out) ^ 1);
deba@491
  1201
      if (arc.id == -2) arc.id = -1;
deba@491
  1202
    }
deba@491
  1203
deba@491
  1204
    void nextIn(Arc& arc) const {
deba@491
  1205
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
deba@491
  1206
      if (arc.id == -2) arc.id = -1;
deba@491
  1207
    }
deba@491
  1208
deba@491
  1209
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
deba@559
  1210
      int de = (*_nodes)[node].first_out;
deba@491
  1211
      if (de != -1 ) {
deba@491
  1212
        arc.id = de / 2;
deba@491
  1213
        dir = ((de & 1) == 1);
deba@491
  1214
      } else {
deba@491
  1215
        arc.id = -1;
deba@491
  1216
        dir = true;
deba@491
  1217
      }
deba@491
  1218
    }
deba@491
  1219
    void nextInc(Edge &arc, bool& dir) const {
deba@491
  1220
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
deba@491
  1221
      if (de != -1 ) {
deba@491
  1222
        arc.id = de / 2;
deba@491
  1223
        dir = ((de & 1) == 1);
deba@491
  1224
      } else {
deba@491
  1225
        arc.id = -1;
deba@491
  1226
        dir = true;
deba@491
  1227
      }
deba@491
  1228
    }
deba@491
  1229
deba@491
  1230
    static bool direction(Arc arc) {
deba@491
  1231
      return (arc.id & 1) == 1;
deba@491
  1232
    }
deba@491
  1233
deba@491
  1234
    static Arc direct(Edge edge, bool dir) {
deba@491
  1235
      return Arc(edge.id * 2 + (dir ? 1 : 0));
deba@491
  1236
    }
deba@491
  1237
deba@559
  1238
    int id(Node node) const { return _graph->id(node); }
deba@491
  1239
    static int id(Arc arc) { return arc.id; }
deba@491
  1240
    static int id(Edge arc) { return arc.id; }
deba@491
  1241
deba@559
  1242
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
deba@491
  1243
    static Arc arcFromId(int id) { return Arc(id); }
deba@491
  1244
    static Edge edgeFromId(int id) { return Edge(id);}
deba@491
  1245
deba@559
  1246
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
  1247
    int maxArcId() const { return arcs.size() - 1; }
deba@491
  1248
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@491
  1249
deba@491
  1250
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
deba@491
  1251
    Node target(Arc e) const { return arcs[e.id].target; }
deba@491
  1252
deba@491
  1253
    Node u(Edge e) const { return arcs[2 * e.id].target; }
deba@491
  1254
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
deba@491
  1255
deba@559
  1256
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
  1257
deba@491
  1258
    NodeNotifier& notifier(Node) const {
deba@559
  1259
      return _graph->notifier(Node());
deba@491
  1260
    }
deba@491
  1261
deba@559
  1262
    template <typename V>
deba@559
  1263
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
  1264
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
  1265
deba@491
  1266
    public:
deba@491
  1267
deba@559
  1268
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
deba@559
  1269
        : Parent(*arcset._graph) { }
deba@491
  1270
deba@559
  1271
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
deba@559
  1272
        : Parent(*arcset._graph, value) { }
deba@491
  1273
deba@491
  1274
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
  1275
        return operator=<NodeMap>(cmap);
deba@491
  1276
      }
deba@491
  1277
deba@491
  1278
      template <typename CMap>
deba@491
  1279
      NodeMap& operator=(const CMap& cmap) {
deba@491
  1280
        Parent::operator=(cmap);
deba@491
  1281
        return *this;
deba@491
  1282
      }
deba@491
  1283
    };
deba@491
  1284
deba@491
  1285
  };
deba@491
  1286
kpeter@707
  1287
  /// \ingroup graphs
deba@491
  1288
  ///
deba@491
  1289
  /// \brief Graph using a node set of another digraph or graph and an
deba@491
  1290
  /// own edge set.
deba@491
  1291
  ///
deba@491
  1292
  /// This structure can be used to establish another graph over a
deba@491
  1293
  /// node set of an existing one. This class uses the same Node type
deba@491
  1294
  /// as the underlying graph, and each valid node of the original
deba@491
  1295
  /// graph is valid in this arc set, therefore the node objects of
deba@491
  1296
  /// the original graph can be used directly with this class. The
deba@491
  1297
  /// node handling functions (id handling, observing, and iterators)
deba@491
  1298
  /// works equivalently as in the original graph.
deba@491
  1299
  ///
deba@559
  1300
  /// \param GR The type of the graph which shares its node set
deba@491
  1301
  /// with this class. Its interface must conform to the
deba@491
  1302
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
  1303
  ///  concept.
deba@491
  1304
  ///
deba@491
  1305
  /// This implementation is slightly faster than the \c ListEdgeSet,
deba@491
  1306
  /// because it uses continuous storage for edges and it uses just
deba@491
  1307
  /// single-linked lists for enumerate incident edges. Therefore the
deba@491
  1308
  /// edges cannot be erased from the edge sets.
deba@491
  1309
  ///
kpeter@834
  1310
  /// This class fully conforms to the \ref concepts::Graph "Graph"
kpeter@834
  1311
  /// concept.
kpeter@834
  1312
  /// It provides only linear time counting for nodes, edges and arcs.
kpeter@834
  1313
  ///
deba@491
  1314
  /// \warning If a node is erased from the underlying graph and this
deba@491
  1315
  /// node is incident to one edge in the edge set, then the edge set
deba@491
  1316
  /// is invalidated, and it cannot be used anymore. The validity can
deba@491
  1317
  /// be checked with the \c valid() member function.
deba@559
  1318
  template <typename GR>
deba@559
  1319
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
kpeter@664
  1320
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
deba@491
  1321
deba@491
  1322
  public:
deba@491
  1323
deba@491
  1324
    typedef typename Parent::Node Node;
deba@491
  1325
    typedef typename Parent::Arc Arc;
deba@491
  1326
    typedef typename Parent::Edge Edge;
deba@491
  1327
deba@491
  1328
  protected:
deba@491
  1329
deba@491
  1330
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
  1331
deba@491
  1332
    void eraseNode(const Node& node) {
deba@491
  1333
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
deba@491
  1334
        return;
deba@491
  1335
      }
deba@491
  1336
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@491
  1337
    }
deba@491
  1338
deba@491
  1339
    void clearNodes() {
deba@491
  1340
      Parent::clear();
deba@491
  1341
    }
deba@491
  1342
deba@491
  1343
    class NodesImpl : public NodesImplBase {
deba@491
  1344
      typedef NodesImplBase Parent;
deba@491
  1345
kpeter@664
  1346
    public:
deba@559
  1347
      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
deba@491
  1348
        : Parent(graph), _arcset(arcset) {}
deba@491
  1349
deba@491
  1350
      virtual ~NodesImpl() {}
deba@491
  1351
deba@491
  1352
      bool attached() const {
deba@491
  1353
        return Parent::attached();
deba@491
  1354
      }
deba@491
  1355
deba@491
  1356
    protected:
deba@491
  1357
deba@491
  1358
      virtual void erase(const Node& node) {
deba@491
  1359
        try {
deba@491
  1360
          _arcset.eraseNode(node);
deba@491
  1361
          Parent::erase(node);
deba@491
  1362
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1363
          Parent::clear();
deba@491
  1364
          throw;
deba@491
  1365
        }
deba@491
  1366
      }
deba@491
  1367
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
  1368
        try {
deba@491
  1369
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
  1370
            _arcset.eraseNode(nodes[i]);
deba@491
  1371
          }
deba@491
  1372
          Parent::erase(nodes);
deba@491
  1373
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1374
          Parent::clear();
deba@491
  1375
          throw;
deba@491
  1376
        }
deba@491
  1377
      }
deba@491
  1378
      virtual void clear() {
deba@491
  1379
        _arcset.clearNodes();
deba@491
  1380
        Parent::clear();
deba@491
  1381
      }
deba@491
  1382
deba@491
  1383
    private:
deba@491
  1384
      SmartEdgeSet& _arcset;
deba@491
  1385
    };
deba@491
  1386
deba@559
  1387
    NodesImpl _nodes;
deba@491
  1388
deba@491
  1389
  public:
deba@491
  1390
deba@491
  1391
    /// \brief Constructor of the EdgeSet.
deba@491
  1392
    ///
deba@491
  1393
    /// Constructor of the EdgeSet.
deba@559
  1394
    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
deba@559
  1395
      Parent::initalize(graph, _nodes);
deba@491
  1396
    }
deba@491
  1397
deba@491
  1398
    /// \brief Add a new edge to the graph.
deba@491
  1399
    ///
deba@491
  1400
    /// Add a new edge to the graph with node \c u
deba@491
  1401
    /// and node \c v endpoints.
kpeter@606
  1402
    /// \return The new edge.
deba@491
  1403
    Edge addEdge(const Node& u, const Node& v) {
deba@491
  1404
      return Parent::addEdge(u, v);
deba@491
  1405
    }
deba@491
  1406
deba@491
  1407
    /// \brief Validity check
deba@491
  1408
    ///
deba@491
  1409
    /// This functions gives back false if the EdgeSet is
deba@491
  1410
    /// invalidated. It occurs when a node in the underlying graph is
deba@491
  1411
    /// erased and it is not isolated in the EdgeSet.
deba@491
  1412
    bool valid() const {
deba@559
  1413
      return _nodes.attached();
deba@491
  1414
    }
deba@491
  1415
deba@491
  1416
  };
deba@491
  1417
deba@491
  1418
}
deba@491
  1419
deba@491
  1420
#endif