lemon/edge_set.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 707 d9cf3b5858ae
child 825 a143f19f465b
child 1081 f1398882a928
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
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
 *
deba@491
     5
 * Copyright (C) 2003-2008
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
  ///
deba@559
   258
  /// \param GR The type of the graph which shares its node set with
deba@491
   259
  /// this class. Its interface must conform to the
deba@491
   260
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
   261
  /// concept.
deba@491
   262
  ///
kpeter@606
   263
  /// This class fully conforms to the \ref concepts::Digraph
deba@491
   264
  /// "Digraph" concept.
deba@559
   265
  template <typename GR>
deba@559
   266
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
kpeter@664
   267
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
deba@491
   268
deba@491
   269
  public:
deba@491
   270
deba@491
   271
    typedef typename Parent::Node Node;
deba@491
   272
    typedef typename Parent::Arc Arc;
deba@491
   273
deba@491
   274
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
   275
deba@491
   276
    void eraseNode(const Node& node) {
deba@491
   277
      Arc arc;
deba@491
   278
      Parent::firstOut(arc, node);
deba@491
   279
      while (arc != INVALID ) {
deba@491
   280
        erase(arc);
deba@491
   281
        Parent::firstOut(arc, node);
deba@491
   282
      }
deba@491
   283
deba@491
   284
      Parent::firstIn(arc, node);
deba@491
   285
      while (arc != INVALID ) {
deba@491
   286
        erase(arc);
deba@491
   287
        Parent::firstIn(arc, node);
deba@491
   288
      }
deba@491
   289
    }
deba@491
   290
deba@491
   291
    void clearNodes() {
deba@491
   292
      Parent::clear();
deba@491
   293
    }
deba@491
   294
deba@491
   295
    class NodesImpl : public NodesImplBase {
deba@491
   296
      typedef NodesImplBase Parent;
deba@491
   297
kpeter@664
   298
    public:
deba@559
   299
      NodesImpl(const GR& graph, ListArcSet& arcset)
deba@491
   300
        : Parent(graph), _arcset(arcset) {}
deba@491
   301
deba@491
   302
      virtual ~NodesImpl() {}
deba@491
   303
deba@491
   304
    protected:
deba@491
   305
deba@491
   306
      virtual void erase(const Node& node) {
deba@491
   307
        _arcset.eraseNode(node);
deba@491
   308
        Parent::erase(node);
deba@491
   309
      }
deba@491
   310
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
   311
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
   312
          _arcset.eraseNode(nodes[i]);
deba@491
   313
        }
deba@491
   314
        Parent::erase(nodes);
deba@491
   315
      }
deba@491
   316
      virtual void clear() {
deba@491
   317
        _arcset.clearNodes();
deba@491
   318
        Parent::clear();
deba@491
   319
      }
deba@491
   320
deba@491
   321
    private:
deba@491
   322
      ListArcSet& _arcset;
deba@491
   323
    };
deba@491
   324
deba@559
   325
    NodesImpl _nodes;
deba@491
   326
deba@491
   327
  public:
deba@491
   328
deba@491
   329
    /// \brief Constructor of the ArcSet.
deba@491
   330
    ///
deba@491
   331
    /// Constructor of the ArcSet.
deba@559
   332
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
deba@559
   333
      Parent::initalize(graph, _nodes);
deba@491
   334
    }
deba@491
   335
deba@491
   336
    /// \brief Add a new arc to the digraph.
deba@491
   337
    ///
deba@491
   338
    /// Add a new arc to the digraph with source node \c s
deba@491
   339
    /// and target node \c t.
kpeter@606
   340
    /// \return The new arc.
deba@491
   341
    Arc addArc(const Node& s, const Node& t) {
deba@491
   342
      return Parent::addArc(s, t);
deba@491
   343
    }
deba@491
   344
deba@491
   345
    /// \brief Erase an arc from the digraph.
deba@491
   346
    ///
deba@491
   347
    /// Erase an arc \c a from the digraph.
deba@491
   348
    void erase(const Arc& a) {
deba@491
   349
      return Parent::erase(a);
deba@491
   350
    }
deba@491
   351
deba@491
   352
  };
deba@491
   353
deba@559
   354
  template <typename GR>
deba@491
   355
  class ListEdgeSetBase {
deba@491
   356
  public:
deba@491
   357
deba@559
   358
    typedef typename GR::Node Node;
deba@559
   359
    typedef typename GR::NodeIt NodeIt;
deba@491
   360
deba@491
   361
  protected:
deba@491
   362
deba@491
   363
    struct NodeT {
deba@491
   364
      int first_out;
deba@491
   365
      NodeT() : first_out(-1) {}
deba@491
   366
    };
deba@491
   367
deba@559
   368
    typedef typename ItemSetTraits<GR, Node>::
deba@491
   369
    template Map<NodeT>::Type NodesImplBase;
deba@491
   370
deba@559
   371
    NodesImplBase* _nodes;
deba@491
   372
deba@491
   373
    struct ArcT {
deba@491
   374
      Node target;
deba@491
   375
      int prev_out, next_out;
deba@491
   376
      ArcT() : prev_out(-1), next_out(-1) {}
deba@491
   377
    };
deba@491
   378
deba@491
   379
    std::vector<ArcT> arcs;
deba@491
   380
deba@491
   381
    int first_arc;
deba@491
   382
    int first_free_arc;
deba@491
   383
deba@559
   384
    const GR* _graph;
deba@491
   385
deba@559
   386
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
   387
      _graph = &graph;
deba@559
   388
      _nodes = &nodes;
deba@491
   389
    }
deba@491
   390
deba@491
   391
  public:
deba@491
   392
deba@491
   393
    class Edge {
deba@491
   394
      friend class ListEdgeSetBase;
deba@491
   395
    protected:
deba@491
   396
deba@491
   397
      int id;
deba@491
   398
      explicit Edge(int _id) { id = _id;}
deba@491
   399
deba@491
   400
    public:
deba@491
   401
      Edge() {}
deba@491
   402
      Edge (Invalid) { id = -1; }
deba@491
   403
      bool operator==(const Edge& arc) const {return id == arc.id;}
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
    };
deba@491
   407
deba@491
   408
    class Arc {
deba@491
   409
      friend class ListEdgeSetBase;
deba@491
   410
    protected:
deba@491
   411
      Arc(int _id) : id(_id) {}
deba@491
   412
      int id;
deba@491
   413
    public:
deba@491
   414
      operator Edge() const { return edgeFromId(id / 2); }
deba@491
   415
deba@491
   416
      Arc() {}
deba@491
   417
      Arc(Invalid) : id(-1) {}
deba@491
   418
      bool operator==(const Arc& arc) const { return id == arc.id; }
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
    };
deba@491
   422
deba@491
   423
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
deba@491
   424
kpeter@717
   425
    Node addNode() {
kpeter@717
   426
      LEMON_ASSERT(false,
kpeter@717
   427
        "This graph structure does not support node insertion");
kpeter@717
   428
      return INVALID; // avoid warning
kpeter@717
   429
    }
kpeter@717
   430
deba@491
   431
    Edge addEdge(const Node& u, const Node& v) {
deba@491
   432
      int n;
deba@491
   433
deba@491
   434
      if (first_free_arc == -1) {
deba@491
   435
        n = arcs.size();
deba@491
   436
        arcs.push_back(ArcT());
deba@491
   437
        arcs.push_back(ArcT());
deba@491
   438
      } else {
deba@491
   439
        n = first_free_arc;
deba@491
   440
        first_free_arc = arcs[n].next_out;
deba@491
   441
      }
deba@491
   442
deba@491
   443
      arcs[n].target = u;
deba@491
   444
      arcs[n | 1].target = v;
deba@491
   445
deba@559
   446
      arcs[n].next_out = (*_nodes)[v].first_out;
deba@559
   447
      if ((*_nodes)[v].first_out != -1) {
deba@559
   448
        arcs[(*_nodes)[v].first_out].prev_out = n;
deba@491
   449
      }
deba@559
   450
      (*_nodes)[v].first_out = n;
deba@491
   451
      arcs[n].prev_out = -1;
deba@491
   452
deba@559
   453
      if ((*_nodes)[u].first_out != -1) {
deba@559
   454
        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
deba@491
   455
      }
deba@559
   456
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
deba@559
   457
      (*_nodes)[u].first_out = (n | 1);
deba@491
   458
      arcs[n | 1].prev_out = -1;
deba@491
   459
deba@491
   460
      return Edge(n / 2);
deba@491
   461
    }
deba@491
   462
deba@491
   463
    void erase(const Edge& arc) {
deba@491
   464
      int n = arc.id * 2;
deba@491
   465
deba@491
   466
      if (arcs[n].next_out != -1) {
deba@491
   467
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
deba@491
   468
      }
deba@491
   469
deba@491
   470
      if (arcs[n].prev_out != -1) {
deba@491
   471
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
deba@491
   472
      } else {
deba@559
   473
        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
deba@491
   474
      }
deba@491
   475
deba@491
   476
      if (arcs[n | 1].next_out != -1) {
deba@491
   477
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
deba@491
   478
      }
deba@491
   479
deba@491
   480
      if (arcs[n | 1].prev_out != -1) {
deba@491
   481
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
deba@491
   482
      } else {
deba@559
   483
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
deba@491
   484
      }
deba@491
   485
deba@491
   486
      arcs[n].next_out = first_free_arc;
deba@491
   487
      first_free_arc = n;
deba@491
   488
deba@491
   489
    }
deba@491
   490
deba@491
   491
    void clear() {
deba@491
   492
      Node node;
deba@491
   493
      for (first(node); node != INVALID; next(node)) {
deba@559
   494
        (*_nodes)[node].first_out = -1;
deba@491
   495
      }
deba@491
   496
      arcs.clear();
deba@491
   497
      first_arc = -1;
deba@491
   498
      first_free_arc = -1;
deba@491
   499
    }
deba@491
   500
deba@491
   501
    void first(Node& node) const {
deba@559
   502
      _graph->first(node);
deba@491
   503
    }
deba@491
   504
deba@491
   505
    void next(Node& node) const {
deba@559
   506
      _graph->next(node);
deba@491
   507
    }
deba@491
   508
deba@491
   509
    void first(Arc& arc) const {
deba@491
   510
      Node node;
deba@491
   511
      first(node);
deba@559
   512
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
deba@491
   513
        next(node);
deba@491
   514
      }
deba@559
   515
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
deba@491
   516
    }
deba@491
   517
deba@491
   518
    void next(Arc& arc) const {
deba@491
   519
      if (arcs[arc.id].next_out != -1) {
deba@491
   520
        arc.id = arcs[arc.id].next_out;
deba@491
   521
      } else {
deba@491
   522
        Node node = arcs[arc.id ^ 1].target;
deba@491
   523
        next(node);
deba@559
   524
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
deba@491
   525
          next(node);
deba@491
   526
        }
deba@559
   527
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
deba@491
   528
      }
deba@491
   529
    }
deba@491
   530
deba@491
   531
    void first(Edge& edge) const {
deba@491
   532
      Node node;
deba@491
   533
      first(node);
deba@491
   534
      while (node != INVALID) {
deba@559
   535
        edge.id = (*_nodes)[node].first_out;
deba@491
   536
        while ((edge.id & 1) != 1) {
deba@491
   537
          edge.id = arcs[edge.id].next_out;
deba@491
   538
        }
deba@491
   539
        if (edge.id != -1) {
deba@491
   540
          edge.id /= 2;
deba@491
   541
          return;
deba@491
   542
        }
deba@491
   543
        next(node);
deba@491
   544
      }
deba@491
   545
      edge.id = -1;
deba@491
   546
    }
deba@491
   547
deba@491
   548
    void next(Edge& edge) const {
deba@491
   549
      Node node = arcs[edge.id * 2].target;
deba@491
   550
      edge.id = arcs[(edge.id * 2) | 1].next_out;
deba@491
   551
      while ((edge.id & 1) != 1) {
deba@491
   552
        edge.id = arcs[edge.id].next_out;
deba@491
   553
      }
deba@491
   554
      if (edge.id != -1) {
deba@491
   555
        edge.id /= 2;
deba@491
   556
        return;
deba@491
   557
      }
deba@491
   558
      next(node);
deba@491
   559
      while (node != INVALID) {
deba@559
   560
        edge.id = (*_nodes)[node].first_out;
deba@491
   561
        while ((edge.id & 1) != 1) {
deba@491
   562
          edge.id = arcs[edge.id].next_out;
deba@491
   563
        }
deba@491
   564
        if (edge.id != -1) {
deba@491
   565
          edge.id /= 2;
deba@491
   566
          return;
deba@491
   567
        }
deba@491
   568
        next(node);
deba@491
   569
      }
deba@491
   570
      edge.id = -1;
deba@491
   571
    }
deba@491
   572
deba@491
   573
    void firstOut(Arc& arc, const Node& node) const {
deba@559
   574
      arc.id = (*_nodes)[node].first_out;
deba@491
   575
    }
deba@491
   576
deba@491
   577
    void nextOut(Arc& arc) const {
deba@491
   578
      arc.id = arcs[arc.id].next_out;
deba@491
   579
    }
deba@491
   580
deba@491
   581
    void firstIn(Arc& arc, const Node& node) const {
deba@559
   582
      arc.id = (((*_nodes)[node].first_out) ^ 1);
deba@491
   583
      if (arc.id == -2) arc.id = -1;
deba@491
   584
    }
deba@491
   585
deba@491
   586
    void nextIn(Arc& arc) const {
deba@491
   587
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
deba@491
   588
      if (arc.id == -2) arc.id = -1;
deba@491
   589
    }
deba@491
   590
deba@491
   591
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
deba@559
   592
      int de = (*_nodes)[node].first_out;
deba@491
   593
      if (de != -1 ) {
deba@491
   594
        arc.id = de / 2;
deba@491
   595
        dir = ((de & 1) == 1);
deba@491
   596
      } else {
deba@491
   597
        arc.id = -1;
deba@491
   598
        dir = true;
deba@491
   599
      }
deba@491
   600
    }
deba@491
   601
    void nextInc(Edge &arc, bool& dir) const {
deba@491
   602
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
deba@491
   603
      if (de != -1 ) {
deba@491
   604
        arc.id = de / 2;
deba@491
   605
        dir = ((de & 1) == 1);
deba@491
   606
      } else {
deba@491
   607
        arc.id = -1;
deba@491
   608
        dir = true;
deba@491
   609
      }
deba@491
   610
    }
deba@491
   611
deba@491
   612
    static bool direction(Arc arc) {
deba@491
   613
      return (arc.id & 1) == 1;
deba@491
   614
    }
deba@491
   615
deba@491
   616
    static Arc direct(Edge edge, bool dir) {
deba@491
   617
      return Arc(edge.id * 2 + (dir ? 1 : 0));
deba@491
   618
    }
deba@491
   619
deba@559
   620
    int id(const Node& node) const { return _graph->id(node); }
deba@491
   621
    static int id(Arc e) { return e.id; }
deba@491
   622
    static int id(Edge e) { return e.id; }
deba@491
   623
deba@559
   624
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
deba@491
   625
    static Arc arcFromId(int id) { return Arc(id);}
deba@491
   626
    static Edge edgeFromId(int id) { return Edge(id);}
deba@491
   627
deba@559
   628
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
   629
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@491
   630
    int maxArcId() const { return arcs.size()-1; }
deba@491
   631
deba@491
   632
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
deba@491
   633
    Node target(Arc e) const { return arcs[e.id].target; }
deba@491
   634
deba@491
   635
    Node u(Edge e) const { return arcs[2 * e.id].target; }
deba@491
   636
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
deba@491
   637
deba@559
   638
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
   639
deba@491
   640
    NodeNotifier& notifier(Node) const {
deba@559
   641
      return _graph->notifier(Node());
deba@491
   642
    }
deba@491
   643
deba@559
   644
    template <typename V>
deba@559
   645
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
   646
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
   647
deba@491
   648
    public:
deba@491
   649
deba@559
   650
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
deba@559
   651
        : Parent(*arcset._graph) {}
deba@491
   652
deba@559
   653
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
deba@559
   654
        : Parent(*arcset._graph, value) {}
deba@491
   655
deba@491
   656
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
   657
        return operator=<NodeMap>(cmap);
deba@491
   658
      }
deba@491
   659
deba@491
   660
      template <typename CMap>
deba@491
   661
      NodeMap& operator=(const CMap& cmap) {
deba@491
   662
        Parent::operator=(cmap);
deba@491
   663
        return *this;
deba@491
   664
      }
deba@491
   665
    };
deba@491
   666
deba@491
   667
  };
deba@491
   668
kpeter@707
   669
  /// \ingroup graphs
deba@491
   670
  ///
deba@491
   671
  /// \brief Graph using a node set of another digraph or graph and an
deba@491
   672
  /// own edge set.
deba@491
   673
  ///
deba@491
   674
  /// This structure can be used to establish another graph over a
deba@491
   675
  /// node set of an existing one. This class uses the same Node type
deba@491
   676
  /// as the underlying graph, and each valid node of the original
deba@491
   677
  /// graph is valid in this arc set, therefore the node objects of
deba@491
   678
  /// the original graph can be used directly with this class. The
deba@491
   679
  /// node handling functions (id handling, observing, and iterators)
deba@491
   680
  /// works equivalently as in the original graph.
deba@491
   681
  ///
deba@491
   682
  /// This implementation is based on doubly-linked lists, from each
deba@491
   683
  /// node the incident edges make up lists, therefore one edge can be
deba@491
   684
  /// erased in constant time. It also makes possible, that node can
deba@491
   685
  /// be removed from the underlying graph, in this case all edges
deba@491
   686
  /// incident to the given node is erased from the arc set.
deba@491
   687
  ///
deba@559
   688
  /// \param GR The type of the graph which shares its node set
deba@491
   689
  /// with this class. Its interface must conform to the
deba@491
   690
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
   691
  /// concept.
deba@491
   692
  ///
kpeter@606
   693
  /// This class fully conforms to the \ref concepts::Graph "Graph"
deba@491
   694
  /// concept.
deba@559
   695
  template <typename GR>
deba@559
   696
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
kpeter@664
   697
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
deba@491
   698
deba@491
   699
  public:
deba@491
   700
deba@491
   701
    typedef typename Parent::Node Node;
deba@491
   702
    typedef typename Parent::Arc Arc;
deba@491
   703
    typedef typename Parent::Edge Edge;
deba@491
   704
deba@491
   705
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
   706
deba@491
   707
    void eraseNode(const Node& node) {
deba@491
   708
      Arc arc;
deba@491
   709
      Parent::firstOut(arc, node);
deba@491
   710
      while (arc != INVALID ) {
deba@491
   711
        erase(arc);
deba@491
   712
        Parent::firstOut(arc, node);
deba@491
   713
      }
deba@491
   714
deba@491
   715
    }
deba@491
   716
deba@491
   717
    void clearNodes() {
deba@491
   718
      Parent::clear();
deba@491
   719
    }
deba@491
   720
deba@491
   721
    class NodesImpl : public NodesImplBase {
deba@491
   722
      typedef NodesImplBase Parent;
deba@491
   723
kpeter@664
   724
    public:
deba@559
   725
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
deba@491
   726
        : Parent(graph), _arcset(arcset) {}
deba@491
   727
deba@491
   728
      virtual ~NodesImpl() {}
deba@491
   729
deba@491
   730
    protected:
deba@491
   731
deba@491
   732
      virtual void erase(const Node& node) {
deba@491
   733
        _arcset.eraseNode(node);
deba@491
   734
        Parent::erase(node);
deba@491
   735
      }
deba@491
   736
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
   737
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
   738
          _arcset.eraseNode(nodes[i]);
deba@491
   739
        }
deba@491
   740
        Parent::erase(nodes);
deba@491
   741
      }
deba@491
   742
      virtual void clear() {
deba@491
   743
        _arcset.clearNodes();
deba@491
   744
        Parent::clear();
deba@491
   745
      }
deba@491
   746
deba@491
   747
    private:
deba@491
   748
      ListEdgeSet& _arcset;
deba@491
   749
    };
deba@491
   750
deba@559
   751
    NodesImpl _nodes;
deba@491
   752
deba@491
   753
  public:
deba@491
   754
deba@491
   755
    /// \brief Constructor of the EdgeSet.
deba@491
   756
    ///
deba@491
   757
    /// Constructor of the EdgeSet.
deba@559
   758
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
deba@559
   759
      Parent::initalize(graph, _nodes);
deba@491
   760
    }
deba@491
   761
deba@491
   762
    /// \brief Add a new edge to the graph.
deba@491
   763
    ///
deba@491
   764
    /// Add a new edge to the graph with node \c u
deba@491
   765
    /// and node \c v endpoints.
kpeter@606
   766
    /// \return The new edge.
deba@491
   767
    Edge addEdge(const Node& u, const Node& v) {
deba@491
   768
      return Parent::addEdge(u, v);
deba@491
   769
    }
deba@491
   770
deba@491
   771
    /// \brief Erase an edge from the graph.
deba@491
   772
    ///
deba@491
   773
    /// Erase the edge \c e from the graph.
deba@491
   774
    void erase(const Edge& e) {
deba@491
   775
      return Parent::erase(e);
deba@491
   776
    }
deba@491
   777
deba@491
   778
  };
deba@491
   779
deba@559
   780
  template <typename GR>
deba@491
   781
  class SmartArcSetBase {
deba@491
   782
  public:
deba@491
   783
kpeter@664
   784
    typedef typename GR::Node Node;
kpeter@664
   785
    typedef typename GR::NodeIt NodeIt;
deba@491
   786
deba@491
   787
  protected:
deba@491
   788
deba@491
   789
    struct NodeT {
deba@491
   790
      int first_out, first_in;
deba@491
   791
      NodeT() : first_out(-1), first_in(-1) {}
deba@491
   792
    };
deba@491
   793
deba@559
   794
    typedef typename ItemSetTraits<GR, Node>::
deba@491
   795
    template Map<NodeT>::Type NodesImplBase;
deba@491
   796
deba@559
   797
    NodesImplBase* _nodes;
deba@491
   798
deba@491
   799
    struct ArcT {
deba@491
   800
      Node source, target;
deba@491
   801
      int next_out, next_in;
deba@491
   802
      ArcT() {}
deba@491
   803
    };
deba@491
   804
deba@491
   805
    std::vector<ArcT> arcs;
deba@491
   806
deba@559
   807
    const GR* _graph;
deba@491
   808
deba@559
   809
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
   810
      _graph = &graph;
deba@559
   811
      _nodes = &nodes;
deba@491
   812
    }
deba@491
   813
deba@491
   814
  public:
deba@491
   815
deba@491
   816
    class Arc {
deba@559
   817
      friend class SmartArcSetBase<GR>;
deba@491
   818
    protected:
deba@491
   819
      Arc(int _id) : id(_id) {}
deba@491
   820
      int id;
deba@491
   821
    public:
deba@491
   822
      Arc() {}
deba@491
   823
      Arc(Invalid) : id(-1) {}
deba@491
   824
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@491
   825
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@491
   826
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@491
   827
    };
deba@491
   828
deba@491
   829
    SmartArcSetBase() {}
deba@491
   830
kpeter@717
   831
    Node addNode() {
kpeter@717
   832
      LEMON_ASSERT(false,
kpeter@717
   833
        "This graph structure does not support node insertion");
kpeter@717
   834
      return INVALID; // avoid warning
kpeter@717
   835
    }
kpeter@717
   836
deba@491
   837
    Arc addArc(const Node& u, const Node& v) {
deba@491
   838
      int n = arcs.size();
deba@491
   839
      arcs.push_back(ArcT());
deba@559
   840
      arcs[n].next_in = (*_nodes)[v].first_in;
deba@559
   841
      (*_nodes)[v].first_in = n;
deba@559
   842
      arcs[n].next_out = (*_nodes)[u].first_out;
deba@559
   843
      (*_nodes)[u].first_out = n;
deba@491
   844
      arcs[n].source = u;
deba@491
   845
      arcs[n].target = v;
deba@491
   846
      return Arc(n);
deba@491
   847
    }
deba@491
   848
deba@491
   849
    void clear() {
deba@491
   850
      Node node;
deba@491
   851
      for (first(node); node != INVALID; next(node)) {
deba@559
   852
        (*_nodes)[node].first_in = -1;
deba@559
   853
        (*_nodes)[node].first_out = -1;
deba@491
   854
      }
deba@491
   855
      arcs.clear();
deba@491
   856
    }
deba@491
   857
deba@491
   858
    void first(Node& node) const {
deba@559
   859
      _graph->first(node);
deba@491
   860
    }
deba@491
   861
deba@491
   862
    void next(Node& node) const {
deba@559
   863
      _graph->next(node);
deba@491
   864
    }
deba@491
   865
deba@491
   866
    void first(Arc& arc) const {
deba@491
   867
      arc.id = arcs.size() - 1;
deba@491
   868
    }
deba@491
   869
deba@491
   870
    void next(Arc& arc) const {
deba@491
   871
      --arc.id;
deba@491
   872
    }
deba@491
   873
deba@491
   874
    void firstOut(Arc& arc, const Node& node) const {
deba@559
   875
      arc.id = (*_nodes)[node].first_out;
deba@491
   876
    }
deba@491
   877
deba@491
   878
    void nextOut(Arc& arc) const {
deba@491
   879
      arc.id = arcs[arc.id].next_out;
deba@491
   880
    }
deba@491
   881
deba@491
   882
    void firstIn(Arc& arc, const Node& node) const {
deba@559
   883
      arc.id = (*_nodes)[node].first_in;
deba@491
   884
    }
deba@491
   885
deba@491
   886
    void nextIn(Arc& arc) const {
deba@491
   887
      arc.id = arcs[arc.id].next_in;
deba@491
   888
    }
deba@491
   889
deba@559
   890
    int id(const Node& node) const { return _graph->id(node); }
deba@491
   891
    int id(const Arc& arc) const { return arc.id; }
deba@491
   892
deba@559
   893
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
deba@491
   894
    Arc arcFromId(int ix) const { return Arc(ix); }
deba@491
   895
deba@559
   896
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
   897
    int maxArcId() const { return arcs.size() - 1; }
deba@491
   898
deba@491
   899
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
deba@491
   900
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
deba@491
   901
deba@559
   902
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
   903
deba@491
   904
    NodeNotifier& notifier(Node) const {
deba@559
   905
      return _graph->notifier(Node());
deba@491
   906
    }
deba@491
   907
deba@559
   908
    template <typename V>
deba@559
   909
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
   910
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
   911
deba@491
   912
    public:
deba@491
   913
deba@559
   914
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
deba@559
   915
        : Parent(*arcset._graph) { }
deba@491
   916
deba@559
   917
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
deba@559
   918
        : Parent(*arcset._graph, value) { }
deba@491
   919
deba@491
   920
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
   921
        return operator=<NodeMap>(cmap);
deba@491
   922
      }
deba@491
   923
deba@491
   924
      template <typename CMap>
deba@491
   925
      NodeMap& operator=(const CMap& cmap) {
deba@491
   926
        Parent::operator=(cmap);
deba@491
   927
        return *this;
deba@491
   928
      }
deba@491
   929
    };
deba@491
   930
deba@491
   931
  };
deba@491
   932
deba@491
   933
kpeter@707
   934
  /// \ingroup graphs
deba@491
   935
  ///
deba@491
   936
  /// \brief Digraph using a node set of another digraph or graph and
deba@491
   937
  /// an own arc set.
deba@491
   938
  ///
deba@491
   939
  /// This structure can be used to establish another directed graph
deba@491
   940
  /// over a node set of an existing one. This class uses the same
deba@491
   941
  /// Node type as the underlying graph, and each valid node of the
deba@491
   942
  /// original graph is valid in this arc set, therefore the node
deba@491
   943
  /// objects of the original graph can be used directly with this
deba@491
   944
  /// class. The node handling functions (id handling, observing, and
deba@491
   945
  /// iterators) works equivalently as in the original graph.
deba@491
   946
  ///
deba@559
   947
  /// \param GR The type of the graph which shares its node set with
deba@491
   948
  /// this class. Its interface must conform to the
deba@491
   949
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
   950
  /// concept.
deba@491
   951
  ///
deba@491
   952
  /// This implementation is slightly faster than the \c ListArcSet,
deba@491
   953
  /// because it uses continuous storage for arcs and it uses just
deba@491
   954
  /// single-linked lists for enumerate outgoing and incoming
deba@491
   955
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
deba@491
   956
  ///
deba@491
   957
  /// \warning If a node is erased from the underlying graph and this
deba@491
   958
  /// node is the source or target of one arc in the arc set, then
deba@491
   959
  /// the arc set is invalidated, and it cannot be used anymore. The
deba@491
   960
  /// validity can be checked with the \c valid() member function.
deba@491
   961
  ///
kpeter@606
   962
  /// This class fully conforms to the \ref concepts::Digraph
deba@491
   963
  /// "Digraph" concept.
deba@559
   964
  template <typename GR>
deba@559
   965
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
kpeter@664
   966
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
deba@491
   967
deba@491
   968
  public:
deba@491
   969
deba@491
   970
    typedef typename Parent::Node Node;
deba@491
   971
    typedef typename Parent::Arc Arc;
deba@491
   972
deba@491
   973
  protected:
deba@491
   974
deba@491
   975
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
   976
deba@491
   977
    void eraseNode(const Node& node) {
deba@491
   978
      if (typename Parent::InArcIt(*this, node) == INVALID &&
deba@491
   979
          typename Parent::OutArcIt(*this, node) == INVALID) {
deba@491
   980
        return;
deba@491
   981
      }
deba@491
   982
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@491
   983
    }
deba@491
   984
deba@491
   985
    void clearNodes() {
deba@491
   986
      Parent::clear();
deba@491
   987
    }
deba@491
   988
deba@491
   989
    class NodesImpl : public NodesImplBase {
deba@491
   990
      typedef NodesImplBase Parent;
deba@491
   991
kpeter@664
   992
    public:
deba@559
   993
      NodesImpl(const GR& graph, SmartArcSet& arcset)
deba@491
   994
        : Parent(graph), _arcset(arcset) {}
deba@491
   995
deba@491
   996
      virtual ~NodesImpl() {}
deba@491
   997
deba@491
   998
      bool attached() const {
deba@491
   999
        return Parent::attached();
deba@491
  1000
      }
deba@491
  1001
deba@491
  1002
    protected:
deba@491
  1003
deba@491
  1004
      virtual void erase(const Node& node) {
deba@491
  1005
        try {
deba@491
  1006
          _arcset.eraseNode(node);
deba@491
  1007
          Parent::erase(node);
deba@491
  1008
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1009
          Parent::clear();
deba@491
  1010
          throw;
deba@491
  1011
        }
deba@491
  1012
      }
deba@491
  1013
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
  1014
        try {
deba@491
  1015
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
  1016
            _arcset.eraseNode(nodes[i]);
deba@491
  1017
          }
deba@491
  1018
          Parent::erase(nodes);
deba@491
  1019
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1020
          Parent::clear();
deba@491
  1021
          throw;
deba@491
  1022
        }
deba@491
  1023
      }
deba@491
  1024
      virtual void clear() {
deba@491
  1025
        _arcset.clearNodes();
deba@491
  1026
        Parent::clear();
deba@491
  1027
      }
deba@491
  1028
deba@491
  1029
    private:
deba@491
  1030
      SmartArcSet& _arcset;
deba@491
  1031
    };
deba@491
  1032
deba@559
  1033
    NodesImpl _nodes;
deba@491
  1034
deba@491
  1035
  public:
deba@491
  1036
deba@491
  1037
    /// \brief Constructor of the ArcSet.
deba@491
  1038
    ///
deba@491
  1039
    /// Constructor of the ArcSet.
deba@559
  1040
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
deba@559
  1041
      Parent::initalize(graph, _nodes);
deba@491
  1042
    }
deba@491
  1043
deba@491
  1044
    /// \brief Add a new arc to the digraph.
deba@491
  1045
    ///
deba@491
  1046
    /// Add a new arc to the digraph with source node \c s
deba@491
  1047
    /// and target node \c t.
kpeter@606
  1048
    /// \return The new arc.
deba@491
  1049
    Arc addArc(const Node& s, const Node& t) {
deba@491
  1050
      return Parent::addArc(s, t);
deba@491
  1051
    }
deba@491
  1052
deba@491
  1053
    /// \brief Validity check
deba@491
  1054
    ///
deba@491
  1055
    /// This functions gives back false if the ArcSet is
deba@491
  1056
    /// invalidated. It occurs when a node in the underlying graph is
deba@491
  1057
    /// erased and it is not isolated in the ArcSet.
deba@491
  1058
    bool valid() const {
deba@559
  1059
      return _nodes.attached();
deba@491
  1060
    }
deba@491
  1061
deba@491
  1062
  };
deba@491
  1063
deba@491
  1064
deba@559
  1065
  template <typename GR>
deba@491
  1066
  class SmartEdgeSetBase {
deba@491
  1067
  public:
deba@491
  1068
deba@559
  1069
    typedef typename GR::Node Node;
deba@559
  1070
    typedef typename GR::NodeIt NodeIt;
deba@491
  1071
deba@491
  1072
  protected:
deba@491
  1073
deba@491
  1074
    struct NodeT {
deba@491
  1075
      int first_out;
deba@491
  1076
      NodeT() : first_out(-1) {}
deba@491
  1077
    };
deba@491
  1078
deba@559
  1079
    typedef typename ItemSetTraits<GR, Node>::
deba@491
  1080
    template Map<NodeT>::Type NodesImplBase;
deba@491
  1081
deba@559
  1082
    NodesImplBase* _nodes;
deba@491
  1083
deba@491
  1084
    struct ArcT {
deba@491
  1085
      Node target;
deba@491
  1086
      int next_out;
deba@491
  1087
      ArcT() {}
deba@491
  1088
    };
deba@491
  1089
deba@491
  1090
    std::vector<ArcT> arcs;
deba@491
  1091
deba@559
  1092
    const GR* _graph;
deba@491
  1093
deba@559
  1094
    void initalize(const GR& graph, NodesImplBase& nodes) {
deba@559
  1095
      _graph = &graph;
deba@559
  1096
      _nodes = &nodes;
deba@491
  1097
    }
deba@491
  1098
deba@491
  1099
  public:
deba@491
  1100
deba@491
  1101
    class Edge {
deba@491
  1102
      friend class SmartEdgeSetBase;
deba@491
  1103
    protected:
deba@491
  1104
deba@491
  1105
      int id;
deba@491
  1106
      explicit Edge(int _id) { id = _id;}
deba@491
  1107
deba@491
  1108
    public:
deba@491
  1109
      Edge() {}
deba@491
  1110
      Edge (Invalid) { id = -1; }
deba@491
  1111
      bool operator==(const Edge& arc) const {return id == arc.id;}
deba@491
  1112
      bool operator!=(const Edge& arc) const {return id != arc.id;}
deba@491
  1113
      bool operator<(const Edge& arc) const {return id < arc.id;}
deba@491
  1114
    };
deba@491
  1115
deba@491
  1116
    class Arc {
deba@491
  1117
      friend class SmartEdgeSetBase;
deba@491
  1118
    protected:
deba@491
  1119
      Arc(int _id) : id(_id) {}
deba@491
  1120
      int id;
deba@491
  1121
    public:
deba@491
  1122
      operator Edge() const { return edgeFromId(id / 2); }
deba@491
  1123
deba@491
  1124
      Arc() {}
deba@491
  1125
      Arc(Invalid) : id(-1) {}
deba@491
  1126
      bool operator==(const Arc& arc) const { return id == arc.id; }
deba@491
  1127
      bool operator!=(const Arc& arc) const { return id != arc.id; }
deba@491
  1128
      bool operator<(const Arc& arc) const { return id < arc.id; }
deba@491
  1129
    };
deba@491
  1130
deba@491
  1131
    SmartEdgeSetBase() {}
deba@491
  1132
kpeter@717
  1133
    Node addNode() {
kpeter@717
  1134
      LEMON_ASSERT(false,
kpeter@717
  1135
        "This graph structure does not support node insertion");
kpeter@717
  1136
      return INVALID; // avoid warning
kpeter@717
  1137
    }
kpeter@717
  1138
deba@491
  1139
    Edge addEdge(const Node& u, const Node& v) {
deba@491
  1140
      int n = arcs.size();
deba@491
  1141
      arcs.push_back(ArcT());
deba@491
  1142
      arcs.push_back(ArcT());
deba@491
  1143
deba@491
  1144
      arcs[n].target = u;
deba@491
  1145
      arcs[n | 1].target = v;
deba@491
  1146
deba@559
  1147
      arcs[n].next_out = (*_nodes)[v].first_out;
deba@559
  1148
      (*_nodes)[v].first_out = n;
deba@491
  1149
deba@559
  1150
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
deba@559
  1151
      (*_nodes)[u].first_out = (n | 1);
deba@491
  1152
deba@491
  1153
      return Edge(n / 2);
deba@491
  1154
    }
deba@491
  1155
deba@491
  1156
    void clear() {
deba@491
  1157
      Node node;
deba@491
  1158
      for (first(node); node != INVALID; next(node)) {
deba@559
  1159
        (*_nodes)[node].first_out = -1;
deba@491
  1160
      }
deba@491
  1161
      arcs.clear();
deba@491
  1162
    }
deba@491
  1163
deba@491
  1164
    void first(Node& node) const {
deba@559
  1165
      _graph->first(node);
deba@491
  1166
    }
deba@491
  1167
deba@491
  1168
    void next(Node& node) const {
deba@559
  1169
      _graph->next(node);
deba@491
  1170
    }
deba@491
  1171
deba@491
  1172
    void first(Arc& arc) const {
deba@491
  1173
      arc.id = arcs.size() - 1;
deba@491
  1174
    }
deba@491
  1175
deba@491
  1176
    void next(Arc& arc) const {
deba@491
  1177
      --arc.id;
deba@491
  1178
    }
deba@491
  1179
deba@491
  1180
    void first(Edge& arc) const {
deba@491
  1181
      arc.id = arcs.size() / 2 - 1;
deba@491
  1182
    }
deba@491
  1183
deba@491
  1184
    void next(Edge& arc) const {
deba@491
  1185
      --arc.id;
deba@491
  1186
    }
deba@491
  1187
deba@491
  1188
    void firstOut(Arc& arc, const Node& node) const {
deba@559
  1189
      arc.id = (*_nodes)[node].first_out;
deba@491
  1190
    }
deba@491
  1191
deba@491
  1192
    void nextOut(Arc& arc) const {
deba@491
  1193
      arc.id = arcs[arc.id].next_out;
deba@491
  1194
    }
deba@491
  1195
deba@491
  1196
    void firstIn(Arc& arc, const Node& node) const {
deba@559
  1197
      arc.id = (((*_nodes)[node].first_out) ^ 1);
deba@491
  1198
      if (arc.id == -2) arc.id = -1;
deba@491
  1199
    }
deba@491
  1200
deba@491
  1201
    void nextIn(Arc& arc) const {
deba@491
  1202
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
deba@491
  1203
      if (arc.id == -2) arc.id = -1;
deba@491
  1204
    }
deba@491
  1205
deba@491
  1206
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
deba@559
  1207
      int de = (*_nodes)[node].first_out;
deba@491
  1208
      if (de != -1 ) {
deba@491
  1209
        arc.id = de / 2;
deba@491
  1210
        dir = ((de & 1) == 1);
deba@491
  1211
      } else {
deba@491
  1212
        arc.id = -1;
deba@491
  1213
        dir = true;
deba@491
  1214
      }
deba@491
  1215
    }
deba@491
  1216
    void nextInc(Edge &arc, bool& dir) const {
deba@491
  1217
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
deba@491
  1218
      if (de != -1 ) {
deba@491
  1219
        arc.id = de / 2;
deba@491
  1220
        dir = ((de & 1) == 1);
deba@491
  1221
      } else {
deba@491
  1222
        arc.id = -1;
deba@491
  1223
        dir = true;
deba@491
  1224
      }
deba@491
  1225
    }
deba@491
  1226
deba@491
  1227
    static bool direction(Arc arc) {
deba@491
  1228
      return (arc.id & 1) == 1;
deba@491
  1229
    }
deba@491
  1230
deba@491
  1231
    static Arc direct(Edge edge, bool dir) {
deba@491
  1232
      return Arc(edge.id * 2 + (dir ? 1 : 0));
deba@491
  1233
    }
deba@491
  1234
deba@559
  1235
    int id(Node node) const { return _graph->id(node); }
deba@491
  1236
    static int id(Arc arc) { return arc.id; }
deba@491
  1237
    static int id(Edge arc) { return arc.id; }
deba@491
  1238
deba@559
  1239
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
deba@491
  1240
    static Arc arcFromId(int id) { return Arc(id); }
deba@491
  1241
    static Edge edgeFromId(int id) { return Edge(id);}
deba@491
  1242
deba@559
  1243
    int maxNodeId() const { return _graph->maxNodeId(); };
deba@491
  1244
    int maxArcId() const { return arcs.size() - 1; }
deba@491
  1245
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
deba@491
  1246
deba@491
  1247
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
deba@491
  1248
    Node target(Arc e) const { return arcs[e.id].target; }
deba@491
  1249
deba@491
  1250
    Node u(Edge e) const { return arcs[2 * e.id].target; }
deba@491
  1251
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
deba@491
  1252
deba@559
  1253
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
deba@491
  1254
deba@491
  1255
    NodeNotifier& notifier(Node) const {
deba@559
  1256
      return _graph->notifier(Node());
deba@491
  1257
    }
deba@491
  1258
deba@559
  1259
    template <typename V>
deba@559
  1260
    class NodeMap : public GR::template NodeMap<V> {
kpeter@664
  1261
      typedef typename GR::template NodeMap<V> Parent;
kpeter@664
  1262
deba@491
  1263
    public:
deba@491
  1264
deba@559
  1265
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
deba@559
  1266
        : Parent(*arcset._graph) { }
deba@491
  1267
deba@559
  1268
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
deba@559
  1269
        : Parent(*arcset._graph, value) { }
deba@491
  1270
deba@491
  1271
      NodeMap& operator=(const NodeMap& cmap) {
deba@491
  1272
        return operator=<NodeMap>(cmap);
deba@491
  1273
      }
deba@491
  1274
deba@491
  1275
      template <typename CMap>
deba@491
  1276
      NodeMap& operator=(const CMap& cmap) {
deba@491
  1277
        Parent::operator=(cmap);
deba@491
  1278
        return *this;
deba@491
  1279
      }
deba@491
  1280
    };
deba@491
  1281
deba@491
  1282
  };
deba@491
  1283
kpeter@707
  1284
  /// \ingroup graphs
deba@491
  1285
  ///
deba@491
  1286
  /// \brief Graph using a node set of another digraph or graph and an
deba@491
  1287
  /// own edge set.
deba@491
  1288
  ///
deba@491
  1289
  /// This structure can be used to establish another graph over a
deba@491
  1290
  /// node set of an existing one. This class uses the same Node type
deba@491
  1291
  /// as the underlying graph, and each valid node of the original
deba@491
  1292
  /// graph is valid in this arc set, therefore the node objects of
deba@491
  1293
  /// the original graph can be used directly with this class. The
deba@491
  1294
  /// node handling functions (id handling, observing, and iterators)
deba@491
  1295
  /// works equivalently as in the original graph.
deba@491
  1296
  ///
deba@559
  1297
  /// \param GR The type of the graph which shares its node set
deba@491
  1298
  /// with this class. Its interface must conform to the
deba@491
  1299
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
deba@491
  1300
  ///  concept.
deba@491
  1301
  ///
deba@491
  1302
  /// This implementation is slightly faster than the \c ListEdgeSet,
deba@491
  1303
  /// because it uses continuous storage for edges and it uses just
deba@491
  1304
  /// single-linked lists for enumerate incident edges. Therefore the
deba@491
  1305
  /// edges cannot be erased from the edge sets.
deba@491
  1306
  ///
deba@491
  1307
  /// \warning If a node is erased from the underlying graph and this
deba@491
  1308
  /// node is incident to one edge in the edge set, then the edge set
deba@491
  1309
  /// is invalidated, and it cannot be used anymore. The validity can
deba@491
  1310
  /// be checked with the \c valid() member function.
deba@491
  1311
  ///
kpeter@606
  1312
  /// This class fully conforms to the \ref concepts::Graph
deba@491
  1313
  /// "Graph" concept.
deba@559
  1314
  template <typename GR>
deba@559
  1315
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
kpeter@664
  1316
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
deba@491
  1317
deba@491
  1318
  public:
deba@491
  1319
deba@491
  1320
    typedef typename Parent::Node Node;
deba@491
  1321
    typedef typename Parent::Arc Arc;
deba@491
  1322
    typedef typename Parent::Edge Edge;
deba@491
  1323
deba@491
  1324
  protected:
deba@491
  1325
deba@491
  1326
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@491
  1327
deba@491
  1328
    void eraseNode(const Node& node) {
deba@491
  1329
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
deba@491
  1330
        return;
deba@491
  1331
      }
deba@491
  1332
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@491
  1333
    }
deba@491
  1334
deba@491
  1335
    void clearNodes() {
deba@491
  1336
      Parent::clear();
deba@491
  1337
    }
deba@491
  1338
deba@491
  1339
    class NodesImpl : public NodesImplBase {
deba@491
  1340
      typedef NodesImplBase Parent;
deba@491
  1341
kpeter@664
  1342
    public:
deba@559
  1343
      NodesImpl(const GR& graph, SmartEdgeSet& arcset)
deba@491
  1344
        : Parent(graph), _arcset(arcset) {}
deba@491
  1345
deba@491
  1346
      virtual ~NodesImpl() {}
deba@491
  1347
deba@491
  1348
      bool attached() const {
deba@491
  1349
        return Parent::attached();
deba@491
  1350
      }
deba@491
  1351
deba@491
  1352
    protected:
deba@491
  1353
deba@491
  1354
      virtual void erase(const Node& node) {
deba@491
  1355
        try {
deba@491
  1356
          _arcset.eraseNode(node);
deba@491
  1357
          Parent::erase(node);
deba@491
  1358
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1359
          Parent::clear();
deba@491
  1360
          throw;
deba@491
  1361
        }
deba@491
  1362
      }
deba@491
  1363
      virtual void erase(const std::vector<Node>& nodes) {
deba@491
  1364
        try {
deba@491
  1365
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@491
  1366
            _arcset.eraseNode(nodes[i]);
deba@491
  1367
          }
deba@491
  1368
          Parent::erase(nodes);
deba@491
  1369
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@491
  1370
          Parent::clear();
deba@491
  1371
          throw;
deba@491
  1372
        }
deba@491
  1373
      }
deba@491
  1374
      virtual void clear() {
deba@491
  1375
        _arcset.clearNodes();
deba@491
  1376
        Parent::clear();
deba@491
  1377
      }
deba@491
  1378
deba@491
  1379
    private:
deba@491
  1380
      SmartEdgeSet& _arcset;
deba@491
  1381
    };
deba@491
  1382
deba@559
  1383
    NodesImpl _nodes;
deba@491
  1384
deba@491
  1385
  public:
deba@491
  1386
deba@491
  1387
    /// \brief Constructor of the EdgeSet.
deba@491
  1388
    ///
deba@491
  1389
    /// Constructor of the EdgeSet.
deba@559
  1390
    SmartEdgeSet(const GR& graph) : _nodes(graph, *this) {
deba@559
  1391
      Parent::initalize(graph, _nodes);
deba@491
  1392
    }
deba@491
  1393
deba@491
  1394
    /// \brief Add a new edge to the graph.
deba@491
  1395
    ///
deba@491
  1396
    /// Add a new edge to the graph with node \c u
deba@491
  1397
    /// and node \c v endpoints.
kpeter@606
  1398
    /// \return The new edge.
deba@491
  1399
    Edge addEdge(const Node& u, const Node& v) {
deba@491
  1400
      return Parent::addEdge(u, v);
deba@491
  1401
    }
deba@491
  1402
deba@491
  1403
    /// \brief Validity check
deba@491
  1404
    ///
deba@491
  1405
    /// This functions gives back false if the EdgeSet is
deba@491
  1406
    /// invalidated. It occurs when a node in the underlying graph is
deba@491
  1407
    /// erased and it is not isolated in the EdgeSet.
deba@491
  1408
    bool valid() const {
deba@559
  1409
      return _nodes.attached();
deba@491
  1410
    }
deba@491
  1411
deba@491
  1412
  };
deba@491
  1413
deba@491
  1414
}
deba@491
  1415
deba@491
  1416
#endif