lemon/full_graph.h
author Alpar Juttner <alpar@cs.elte.hu>
Fri, 22 May 2015 17:47:18 +0200
changeset 1357 2126945deb6a
parent 1193 c8fa41fcc4a7
permissions -rw-r--r--
Fix wrong iteration in ListGraph snapshot, part II. (#598)
deba@365
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@365
     2
 *
deba@365
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@365
     4
 *
alpar@1270
     5
 * Copyright (C) 2003-2013
deba@365
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@365
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@365
     8
 *
deba@365
     9
 * Permission to use, modify and distribute this software is granted
deba@365
    10
 * provided that this copyright notice appears in all copies. For
deba@365
    11
 * precise terms see the accompanying LICENSE file.
deba@365
    12
 *
deba@365
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@365
    14
 * express or implied, and with no claim as to its suitability for any
deba@365
    15
 * purpose.
deba@365
    16
 *
deba@365
    17
 */
deba@365
    18
deba@365
    19
#ifndef LEMON_FULL_GRAPH_H
deba@365
    20
#define LEMON_FULL_GRAPH_H
deba@365
    21
deba@365
    22
#include <lemon/core.h>
deba@365
    23
#include <lemon/bits/graph_extender.h>
deba@365
    24
deba@365
    25
///\ingroup graphs
deba@365
    26
///\file
kpeter@782
    27
///\brief FullDigraph and FullGraph classes.
kpeter@366
    28
deba@365
    29
namespace lemon {
deba@365
    30
deba@365
    31
  class FullDigraphBase {
deba@365
    32
  public:
deba@365
    33
kpeter@664
    34
    typedef FullDigraphBase Digraph;
deba@365
    35
deba@365
    36
    class Node;
deba@365
    37
    class Arc;
deba@365
    38
deba@365
    39
  protected:
deba@365
    40
deba@365
    41
    int _node_num;
deba@365
    42
    int _arc_num;
deba@365
    43
deba@365
    44
    FullDigraphBase() {}
deba@365
    45
deba@365
    46
    void construct(int n) { _node_num = n; _arc_num = n * n; }
deba@365
    47
deba@365
    48
  public:
deba@365
    49
deba@365
    50
    typedef True NodeNumTag;
deba@365
    51
    typedef True ArcNumTag;
deba@365
    52
deba@365
    53
    Node operator()(int ix) const { return Node(ix); }
kpeter@825
    54
    static int index(const Node& node) { return node._id; }
deba@365
    55
deba@365
    56
    Arc arc(const Node& s, const Node& t) const {
deba@365
    57
      return Arc(s._id * _node_num + t._id);
deba@365
    58
    }
deba@365
    59
deba@365
    60
    int nodeNum() const { return _node_num; }
deba@365
    61
    int arcNum() const { return _arc_num; }
deba@365
    62
deba@365
    63
    int maxNodeId() const { return _node_num - 1; }
deba@365
    64
    int maxArcId() const { return _arc_num - 1; }
deba@365
    65
deba@365
    66
    Node source(Arc arc) const { return arc._id / _node_num; }
deba@365
    67
    Node target(Arc arc) const { return arc._id % _node_num; }
deba@365
    68
deba@365
    69
    static int id(Node node) { return node._id; }
deba@365
    70
    static int id(Arc arc) { return arc._id; }
deba@365
    71
deba@365
    72
    static Node nodeFromId(int id) { return Node(id);}
deba@365
    73
    static Arc arcFromId(int id) { return Arc(id);}
deba@365
    74
deba@365
    75
    typedef True FindArcTag;
deba@365
    76
deba@365
    77
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
kpeter@367
    78
      return prev == INVALID ? arc(s, t) : INVALID;
deba@365
    79
    }
deba@365
    80
deba@365
    81
    class Node {
deba@365
    82
      friend class FullDigraphBase;
deba@365
    83
deba@365
    84
    protected:
deba@365
    85
      int _id;
deba@365
    86
      Node(int id) : _id(id) {}
deba@365
    87
    public:
deba@365
    88
      Node() {}
deba@365
    89
      Node (Invalid) : _id(-1) {}
deba@365
    90
      bool operator==(const Node node) const {return _id == node._id;}
deba@365
    91
      bool operator!=(const Node node) const {return _id != node._id;}
deba@365
    92
      bool operator<(const Node node) const {return _id < node._id;}
deba@365
    93
    };
deba@365
    94
deba@365
    95
    class Arc {
deba@365
    96
      friend class FullDigraphBase;
deba@365
    97
deba@365
    98
    protected:
deba@365
    99
      int _id;  // _node_num * source + target;
deba@365
   100
deba@365
   101
      Arc(int id) : _id(id) {}
deba@365
   102
deba@365
   103
    public:
deba@365
   104
      Arc() { }
deba@365
   105
      Arc (Invalid) { _id = -1; }
deba@365
   106
      bool operator==(const Arc arc) const {return _id == arc._id;}
deba@365
   107
      bool operator!=(const Arc arc) const {return _id != arc._id;}
deba@365
   108
      bool operator<(const Arc arc) const {return _id < arc._id;}
deba@365
   109
    };
deba@365
   110
deba@365
   111
    void first(Node& node) const {
deba@365
   112
      node._id = _node_num - 1;
deba@365
   113
    }
deba@365
   114
deba@365
   115
    static void next(Node& node) {
deba@365
   116
      --node._id;
deba@365
   117
    }
deba@365
   118
deba@365
   119
    void first(Arc& arc) const {
deba@365
   120
      arc._id = _arc_num - 1;
deba@365
   121
    }
deba@365
   122
deba@365
   123
    static void next(Arc& arc) {
deba@365
   124
      --arc._id;
deba@365
   125
    }
deba@365
   126
deba@365
   127
    void firstOut(Arc& arc, const Node& node) const {
deba@365
   128
      arc._id = (node._id + 1) * _node_num - 1;
deba@365
   129
    }
deba@365
   130
deba@365
   131
    void nextOut(Arc& arc) const {
deba@365
   132
      if (arc._id % _node_num == 0) arc._id = 0;
deba@365
   133
      --arc._id;
deba@365
   134
    }
deba@365
   135
deba@365
   136
    void firstIn(Arc& arc, const Node& node) const {
deba@365
   137
      arc._id = _arc_num + node._id - _node_num;
deba@365
   138
    }
deba@365
   139
deba@365
   140
    void nextIn(Arc& arc) const {
deba@365
   141
      arc._id -= _node_num;
deba@365
   142
      if (arc._id < 0) arc._id = -1;
deba@365
   143
    }
deba@365
   144
deba@365
   145
  };
deba@365
   146
deba@365
   147
  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
deba@365
   148
deba@365
   149
  /// \ingroup graphs
deba@365
   150
  ///
kpeter@782
   151
  /// \brief A directed full graph class.
deba@365
   152
  ///
kpeter@782
   153
  /// FullDigraph is a simple and fast implmenetation of directed full
kpeter@782
   154
  /// (complete) graphs. It contains an arc from each node to each node
kpeter@782
   155
  /// (including a loop for each node), therefore the number of arcs
kpeter@782
   156
  /// is the square of the number of nodes.
kpeter@782
   157
  /// This class is completely static and it needs constant memory space.
kpeter@782
   158
  /// Thus you can neither add nor delete nodes or arcs, however
kpeter@782
   159
  /// the structure can be resized using resize().
deba@365
   160
  ///
kpeter@782
   161
  /// This type fully conforms to the \ref concepts::Digraph "Digraph concept".
kpeter@782
   162
  /// Most of its member functions and nested classes are documented
kpeter@782
   163
  /// only in the concept class.
kpeter@366
   164
  ///
kpeter@834
   165
  /// This class provides constant time counting for nodes and arcs.
kpeter@834
   166
  ///
kpeter@782
   167
  /// \note FullDigraph and FullGraph classes are very similar,
kpeter@366
   168
  /// but there are two differences. While this class conforms only
kpeter@782
   169
  /// to the \ref concepts::Digraph "Digraph" concept, FullGraph
kpeter@782
   170
  /// conforms to the \ref concepts::Graph "Graph" concept,
kpeter@782
   171
  /// moreover FullGraph does not contain a loop for each
kpeter@782
   172
  /// node as this class does.
deba@365
   173
  ///
deba@365
   174
  /// \sa FullGraph
deba@365
   175
  class FullDigraph : public ExtendedFullDigraphBase {
kpeter@664
   176
    typedef ExtendedFullDigraphBase Parent;
kpeter@664
   177
deba@365
   178
  public:
deba@365
   179
kpeter@782
   180
    /// \brief Default constructor.
kpeter@782
   181
    ///
kpeter@782
   182
    /// Default constructor. The number of nodes and arcs will be zero.
deba@365
   183
    FullDigraph() { construct(0); }
deba@365
   184
deba@365
   185
    /// \brief Constructor
deba@365
   186
    ///
kpeter@366
   187
    /// Constructor.
deba@365
   188
    /// \param n The number of the nodes.
deba@365
   189
    FullDigraph(int n) { construct(n); }
deba@365
   190
kpeter@366
   191
    /// \brief Resizes the digraph
deba@365
   192
    ///
kpeter@782
   193
    /// This function resizes the digraph. It fully destroys and
kpeter@782
   194
    /// rebuilds the structure, therefore the maps of the digraph will be
kpeter@366
   195
    /// reallocated automatically and the previous values will be lost.
deba@365
   196
    void resize(int n) {
deba@365
   197
      Parent::notifier(Arc()).clear();
deba@365
   198
      Parent::notifier(Node()).clear();
deba@365
   199
      construct(n);
deba@365
   200
      Parent::notifier(Node()).build();
deba@365
   201
      Parent::notifier(Arc()).build();
deba@365
   202
    }
deba@365
   203
deba@365
   204
    /// \brief Returns the node with the given index.
deba@365
   205
    ///
alpar@956
   206
    /// Returns the node with the given index. Since this structure is
kpeter@782
   207
    /// completely static, the nodes can be indexed with integers from
kpeter@782
   208
    /// the range <tt>[0..nodeNum()-1]</tt>.
kpeter@834
   209
    /// The index of a node is the same as its ID.
kpeter@366
   210
    /// \sa index()
deba@365
   211
    Node operator()(int ix) const { return Parent::operator()(ix); }
deba@365
   212
kpeter@366
   213
    /// \brief Returns the index of the given node.
deba@365
   214
    ///
alpar@956
   215
    /// Returns the index of the given node. Since this structure is
kpeter@782
   216
    /// completely static, the nodes can be indexed with integers from
kpeter@782
   217
    /// the range <tt>[0..nodeNum()-1]</tt>.
kpeter@834
   218
    /// The index of a node is the same as its ID.
kpeter@782
   219
    /// \sa operator()()
kpeter@825
   220
    static int index(const Node& node) { return Parent::index(node); }
deba@365
   221
kpeter@366
   222
    /// \brief Returns the arc connecting the given nodes.
deba@365
   223
    ///
kpeter@366
   224
    /// Returns the arc connecting the given nodes.
kpeter@782
   225
    Arc arc(Node u, Node v) const {
deba@365
   226
      return Parent::arc(u, v);
deba@365
   227
    }
deba@365
   228
deba@365
   229
    /// \brief Number of nodes.
deba@365
   230
    int nodeNum() const { return Parent::nodeNum(); }
deba@365
   231
    /// \brief Number of arcs.
deba@365
   232
    int arcNum() const { return Parent::arcNum(); }
deba@365
   233
  };
deba@365
   234
deba@365
   235
deba@365
   236
  class FullGraphBase {
deba@365
   237
  public:
deba@365
   238
deba@365
   239
    typedef FullGraphBase Graph;
deba@365
   240
deba@365
   241
    class Node;
deba@365
   242
    class Arc;
deba@365
   243
    class Edge;
deba@365
   244
deba@365
   245
  protected:
deba@365
   246
kpeter@664
   247
    int _node_num;
kpeter@664
   248
    int _edge_num;
kpeter@664
   249
deba@365
   250
    FullGraphBase() {}
deba@365
   251
deba@365
   252
    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
deba@365
   253
deba@365
   254
    int _uid(int e) const {
deba@365
   255
      int u = e / _node_num;
deba@365
   256
      int v = e % _node_num;
deba@365
   257
      return u < v ? u : _node_num - 2 - u;
deba@365
   258
    }
deba@365
   259
deba@365
   260
    int _vid(int e) const {
deba@365
   261
      int u = e / _node_num;
deba@365
   262
      int v = e % _node_num;
deba@365
   263
      return u < v ? v : _node_num - 1 - v;
deba@365
   264
    }
deba@365
   265
deba@365
   266
    void _uvid(int e, int& u, int& v) const {
deba@365
   267
      u = e / _node_num;
deba@365
   268
      v = e % _node_num;
deba@365
   269
      if  (u >= v) {
deba@365
   270
        u = _node_num - 2 - u;
deba@365
   271
        v = _node_num - 1 - v;
deba@365
   272
      }
deba@365
   273
    }
deba@365
   274
deba@365
   275
    void _stid(int a, int& s, int& t) const {
deba@365
   276
      if ((a & 1) == 1) {
deba@365
   277
        _uvid(a >> 1, s, t);
deba@365
   278
      } else {
deba@365
   279
        _uvid(a >> 1, t, s);
deba@365
   280
      }
deba@365
   281
    }
deba@365
   282
deba@365
   283
    int _eid(int u, int v) const {
deba@365
   284
      if (u < (_node_num - 1) / 2) {
deba@365
   285
        return u * _node_num + v;
deba@365
   286
      } else {
deba@365
   287
        return (_node_num - 1 - u) * _node_num - v - 1;
deba@365
   288
      }
deba@365
   289
    }
deba@365
   290
deba@365
   291
  public:
deba@365
   292
deba@365
   293
    Node operator()(int ix) const { return Node(ix); }
kpeter@825
   294
    static int index(const Node& node) { return node._id; }
deba@365
   295
deba@365
   296
    Edge edge(const Node& u, const Node& v) const {
deba@365
   297
      if (u._id < v._id) {
deba@365
   298
        return Edge(_eid(u._id, v._id));
deba@365
   299
      } else if (u._id != v._id) {
deba@365
   300
        return Edge(_eid(v._id, u._id));
deba@365
   301
      } else {
deba@365
   302
        return INVALID;
deba@365
   303
      }
deba@365
   304
    }
deba@365
   305
deba@365
   306
    Arc arc(const Node& s, const Node& t) const {
deba@365
   307
      if (s._id < t._id) {
deba@365
   308
        return Arc((_eid(s._id, t._id) << 1) | 1);
deba@365
   309
      } else if (s._id != t._id) {
deba@365
   310
        return Arc(_eid(t._id, s._id) << 1);
deba@365
   311
      } else {
deba@365
   312
        return INVALID;
deba@365
   313
      }
deba@365
   314
    }
deba@365
   315
deba@365
   316
    typedef True NodeNumTag;
kpeter@372
   317
    typedef True ArcNumTag;
deba@365
   318
    typedef True EdgeNumTag;
deba@365
   319
deba@365
   320
    int nodeNum() const { return _node_num; }
deba@365
   321
    int arcNum() const { return 2 * _edge_num; }
deba@365
   322
    int edgeNum() const { return _edge_num; }
deba@365
   323
deba@365
   324
    static int id(Node node) { return node._id; }
deba@365
   325
    static int id(Arc arc) { return arc._id; }
deba@365
   326
    static int id(Edge edge) { return edge._id; }
deba@365
   327
deba@365
   328
    int maxNodeId() const { return _node_num-1; }
deba@365
   329
    int maxArcId() const { return 2 * _edge_num-1; }
deba@365
   330
    int maxEdgeId() const { return _edge_num-1; }
deba@365
   331
deba@365
   332
    static Node nodeFromId(int id) { return Node(id);}
deba@365
   333
    static Arc arcFromId(int id) { return Arc(id);}
deba@365
   334
    static Edge edgeFromId(int id) { return Edge(id);}
deba@365
   335
deba@365
   336
    Node u(Edge edge) const {
deba@365
   337
      return Node(_uid(edge._id));
deba@365
   338
    }
deba@365
   339
deba@365
   340
    Node v(Edge edge) const {
deba@365
   341
      return Node(_vid(edge._id));
deba@365
   342
    }
deba@365
   343
deba@365
   344
    Node source(Arc arc) const {
deba@365
   345
      return Node((arc._id & 1) == 1 ?
deba@365
   346
                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
deba@365
   347
    }
deba@365
   348
deba@365
   349
    Node target(Arc arc) const {
deba@365
   350
      return Node((arc._id & 1) == 1 ?
deba@365
   351
                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
deba@365
   352
    }
deba@365
   353
deba@365
   354
    typedef True FindEdgeTag;
kpeter@372
   355
    typedef True FindArcTag;
deba@365
   356
deba@365
   357
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@365
   358
      return prev != INVALID ? INVALID : edge(u, v);
deba@365
   359
    }
deba@365
   360
deba@365
   361
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
deba@365
   362
      return prev != INVALID ? INVALID : arc(s, t);
deba@365
   363
    }
deba@365
   364
deba@365
   365
    class Node {
deba@365
   366
      friend class FullGraphBase;
deba@365
   367
deba@365
   368
    protected:
deba@365
   369
      int _id;
deba@365
   370
      Node(int id) : _id(id) {}
deba@365
   371
    public:
deba@365
   372
      Node() {}
deba@365
   373
      Node (Invalid) { _id = -1; }
deba@365
   374
      bool operator==(const Node node) const {return _id == node._id;}
deba@365
   375
      bool operator!=(const Node node) const {return _id != node._id;}
deba@365
   376
      bool operator<(const Node node) const {return _id < node._id;}
deba@365
   377
    };
deba@365
   378
deba@365
   379
    class Edge {
deba@365
   380
      friend class FullGraphBase;
kpeter@366
   381
      friend class Arc;
deba@365
   382
deba@365
   383
    protected:
deba@365
   384
      int _id;
deba@365
   385
deba@365
   386
      Edge(int id) : _id(id) {}
deba@365
   387
deba@365
   388
    public:
deba@365
   389
      Edge() { }
deba@365
   390
      Edge (Invalid) { _id = -1; }
deba@365
   391
deba@365
   392
      bool operator==(const Edge edge) const {return _id == edge._id;}
deba@365
   393
      bool operator!=(const Edge edge) const {return _id != edge._id;}
deba@365
   394
      bool operator<(const Edge edge) const {return _id < edge._id;}
deba@365
   395
    };
deba@365
   396
deba@365
   397
    class Arc {
deba@365
   398
      friend class FullGraphBase;
deba@365
   399
deba@365
   400
    protected:
deba@365
   401
      int _id;
deba@365
   402
deba@365
   403
      Arc(int id) : _id(id) {}
deba@365
   404
deba@365
   405
    public:
deba@365
   406
      Arc() { }
deba@365
   407
      Arc (Invalid) { _id = -1; }
deba@365
   408
deba@365
   409
      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
deba@365
   410
deba@365
   411
      bool operator==(const Arc arc) const {return _id == arc._id;}
deba@365
   412
      bool operator!=(const Arc arc) const {return _id != arc._id;}
deba@365
   413
      bool operator<(const Arc arc) const {return _id < arc._id;}
deba@365
   414
    };
deba@365
   415
deba@365
   416
    static bool direction(Arc arc) {
deba@365
   417
      return (arc._id & 1) == 1;
deba@365
   418
    }
deba@365
   419
deba@365
   420
    static Arc direct(Edge edge, bool dir) {
deba@365
   421
      return Arc((edge._id << 1) | (dir ? 1 : 0));
deba@365
   422
    }
deba@365
   423
deba@365
   424
    void first(Node& node) const {
deba@365
   425
      node._id = _node_num - 1;
deba@365
   426
    }
deba@365
   427
deba@365
   428
    static void next(Node& node) {
deba@365
   429
      --node._id;
deba@365
   430
    }
deba@365
   431
deba@365
   432
    void first(Arc& arc) const {
deba@365
   433
      arc._id = (_edge_num << 1) - 1;
deba@365
   434
    }
deba@365
   435
deba@365
   436
    static void next(Arc& arc) {
deba@365
   437
      --arc._id;
deba@365
   438
    }
deba@365
   439
deba@365
   440
    void first(Edge& edge) const {
deba@365
   441
      edge._id = _edge_num - 1;
deba@365
   442
    }
deba@365
   443
deba@365
   444
    static void next(Edge& edge) {
deba@365
   445
      --edge._id;
deba@365
   446
    }
deba@365
   447
deba@365
   448
    void firstOut(Arc& arc, const Node& node) const {
deba@365
   449
      int s = node._id, t = _node_num - 1;
deba@365
   450
      if (s < t) {
deba@365
   451
        arc._id = (_eid(s, t) << 1) | 1;
deba@365
   452
      } else {
deba@365
   453
        --t;
deba@365
   454
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
deba@365
   455
      }
deba@365
   456
    }
deba@365
   457
deba@365
   458
    void nextOut(Arc& arc) const {
deba@365
   459
      int s, t;
deba@365
   460
      _stid(arc._id, s, t);
deba@365
   461
      --t;
deba@365
   462
      if (s < t) {
deba@365
   463
        arc._id = (_eid(s, t) << 1) | 1;
deba@365
   464
      } else {
deba@365
   465
        if (s == t) --t;
deba@365
   466
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
deba@365
   467
      }
deba@365
   468
    }
deba@365
   469
deba@365
   470
    void firstIn(Arc& arc, const Node& node) const {
deba@365
   471
      int s = _node_num - 1, t = node._id;
deba@365
   472
      if (s > t) {
deba@365
   473
        arc._id = (_eid(t, s) << 1);
deba@365
   474
      } else {
deba@365
   475
        --s;
deba@365
   476
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
deba@365
   477
      }
deba@365
   478
    }
deba@365
   479
deba@365
   480
    void nextIn(Arc& arc) const {
deba@365
   481
      int s, t;
deba@365
   482
      _stid(arc._id, s, t);
deba@365
   483
      --s;
deba@365
   484
      if (s > t) {
deba@365
   485
        arc._id = (_eid(t, s) << 1);
deba@365
   486
      } else {
deba@365
   487
        if (s == t) --s;
deba@365
   488
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
deba@365
   489
      }
deba@365
   490
    }
deba@365
   491
deba@365
   492
    void firstInc(Edge& edge, bool& dir, const Node& node) const {
deba@365
   493
      int u = node._id, v = _node_num - 1;
deba@365
   494
      if (u < v) {
deba@365
   495
        edge._id = _eid(u, v);
deba@365
   496
        dir = true;
deba@365
   497
      } else {
deba@365
   498
        --v;
deba@365
   499
        edge._id = (v != -1 ? _eid(v, u) : -1);
deba@365
   500
        dir = false;
deba@365
   501
      }
deba@365
   502
    }
deba@365
   503
deba@365
   504
    void nextInc(Edge& edge, bool& dir) const {
deba@365
   505
      int u, v;
deba@365
   506
      if (dir) {
deba@365
   507
        _uvid(edge._id, u, v);
deba@365
   508
        --v;
deba@365
   509
        if (u < v) {
deba@365
   510
          edge._id = _eid(u, v);
deba@365
   511
        } else {
deba@365
   512
          --v;
deba@365
   513
          edge._id = (v != -1 ? _eid(v, u) : -1);
deba@365
   514
          dir = false;
deba@365
   515
        }
deba@365
   516
      } else {
deba@365
   517
        _uvid(edge._id, v, u);
deba@365
   518
        --v;
deba@365
   519
        edge._id = (v != -1 ? _eid(v, u) : -1);
deba@365
   520
      }
deba@365
   521
    }
deba@365
   522
deba@365
   523
  };
deba@365
   524
deba@365
   525
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
deba@365
   526
deba@365
   527
  /// \ingroup graphs
deba@365
   528
  ///
deba@365
   529
  /// \brief An undirected full graph class.
deba@365
   530
  ///
kpeter@782
   531
  /// FullGraph is a simple and fast implmenetation of undirected full
kpeter@782
   532
  /// (complete) graphs. It contains an edge between every distinct pair
kpeter@782
   533
  /// of nodes, therefore the number of edges is <tt>n(n-1)/2</tt>.
kpeter@782
   534
  /// This class is completely static and it needs constant memory space.
kpeter@782
   535
  /// Thus you can neither add nor delete nodes or edges, however
kpeter@782
   536
  /// the structure can be resized using resize().
deba@365
   537
  ///
kpeter@782
   538
  /// This type fully conforms to the \ref concepts::Graph "Graph concept".
kpeter@782
   539
  /// Most of its member functions and nested classes are documented
kpeter@782
   540
  /// only in the concept class.
deba@365
   541
  ///
kpeter@834
   542
  /// This class provides constant time counting for nodes, edges and arcs.
kpeter@834
   543
  ///
kpeter@782
   544
  /// \note FullDigraph and FullGraph classes are very similar,
kpeter@782
   545
  /// but there are two differences. While FullDigraph
kpeter@366
   546
  /// conforms only to the \ref concepts::Digraph "Digraph" concept,
kpeter@366
   547
  /// this class conforms to the \ref concepts::Graph "Graph" concept,
kpeter@782
   548
  /// moreover this class does not contain a loop for each
kpeter@782
   549
  /// node as FullDigraph does.
deba@365
   550
  ///
deba@365
   551
  /// \sa FullDigraph
deba@365
   552
  class FullGraph : public ExtendedFullGraphBase {
kpeter@664
   553
    typedef ExtendedFullGraphBase Parent;
kpeter@664
   554
deba@365
   555
  public:
deba@365
   556
kpeter@782
   557
    /// \brief Default constructor.
kpeter@782
   558
    ///
kpeter@782
   559
    /// Default constructor. The number of nodes and edges will be zero.
deba@365
   560
    FullGraph() { construct(0); }
deba@365
   561
deba@365
   562
    /// \brief Constructor
deba@365
   563
    ///
kpeter@366
   564
    /// Constructor.
deba@365
   565
    /// \param n The number of the nodes.
deba@365
   566
    FullGraph(int n) { construct(n); }
deba@365
   567
kpeter@366
   568
    /// \brief Resizes the graph
deba@365
   569
    ///
kpeter@782
   570
    /// This function resizes the graph. It fully destroys and
kpeter@782
   571
    /// rebuilds the structure, therefore the maps of the graph will be
kpeter@366
   572
    /// reallocated automatically and the previous values will be lost.
deba@365
   573
    void resize(int n) {
deba@365
   574
      Parent::notifier(Arc()).clear();
deba@365
   575
      Parent::notifier(Edge()).clear();
deba@365
   576
      Parent::notifier(Node()).clear();
deba@365
   577
      construct(n);
deba@365
   578
      Parent::notifier(Node()).build();
deba@365
   579
      Parent::notifier(Edge()).build();
deba@365
   580
      Parent::notifier(Arc()).build();
deba@365
   581
    }
deba@365
   582
deba@365
   583
    /// \brief Returns the node with the given index.
deba@365
   584
    ///
alpar@956
   585
    /// Returns the node with the given index. Since this structure is
kpeter@782
   586
    /// completely static, the nodes can be indexed with integers from
kpeter@782
   587
    /// the range <tt>[0..nodeNum()-1]</tt>.
kpeter@834
   588
    /// The index of a node is the same as its ID.
kpeter@366
   589
    /// \sa index()
deba@365
   590
    Node operator()(int ix) const { return Parent::operator()(ix); }
deba@365
   591
kpeter@366
   592
    /// \brief Returns the index of the given node.
deba@365
   593
    ///
alpar@956
   594
    /// Returns the index of the given node. Since this structure is
kpeter@782
   595
    /// completely static, the nodes can be indexed with integers from
kpeter@782
   596
    /// the range <tt>[0..nodeNum()-1]</tt>.
kpeter@834
   597
    /// The index of a node is the same as its ID.
kpeter@782
   598
    /// \sa operator()()
kpeter@825
   599
    static int index(const Node& node) { return Parent::index(node); }
deba@365
   600
kpeter@366
   601
    /// \brief Returns the arc connecting the given nodes.
deba@365
   602
    ///
kpeter@366
   603
    /// Returns the arc connecting the given nodes.
kpeter@782
   604
    Arc arc(Node s, Node t) const {
deba@365
   605
      return Parent::arc(s, t);
deba@365
   606
    }
deba@365
   607
kpeter@782
   608
    /// \brief Returns the edge connecting the given nodes.
deba@365
   609
    ///
kpeter@782
   610
    /// Returns the edge connecting the given nodes.
kpeter@782
   611
    Edge edge(Node u, Node v) const {
deba@365
   612
      return Parent::edge(u, v);
deba@365
   613
    }
kpeter@366
   614
kpeter@366
   615
    /// \brief Number of nodes.
kpeter@366
   616
    int nodeNum() const { return Parent::nodeNum(); }
kpeter@366
   617
    /// \brief Number of arcs.
kpeter@366
   618
    int arcNum() const { return Parent::arcNum(); }
kpeter@366
   619
    /// \brief Number of edges.
kpeter@366
   620
    int edgeNum() const { return Parent::edgeNum(); }
kpeter@366
   621
deba@365
   622
  };
deba@365
   623
deba@1188
   624
  class FullBpGraphBase {
deba@1188
   625
deba@1188
   626
  protected:
deba@1188
   627
deba@1188
   628
    int _red_num, _blue_num;
deba@1188
   629
    int _node_num, _edge_num;
deba@1188
   630
deba@1188
   631
  public:
deba@1188
   632
deba@1188
   633
    typedef FullBpGraphBase Graph;
deba@1188
   634
deba@1188
   635
    class Node;
deba@1188
   636
    class Arc;
deba@1188
   637
    class Edge;
deba@1188
   638
deba@1188
   639
    class Node {
deba@1188
   640
      friend class FullBpGraphBase;
deba@1188
   641
    protected:
deba@1188
   642
deba@1188
   643
      int _id;
deba@1188
   644
      explicit Node(int id) { _id = id;}
deba@1188
   645
deba@1188
   646
    public:
deba@1188
   647
      Node() {}
deba@1188
   648
      Node (Invalid) { _id = -1; }
deba@1188
   649
      bool operator==(const Node& node) const {return _id == node._id;}
deba@1188
   650
      bool operator!=(const Node& node) const {return _id != node._id;}
deba@1188
   651
      bool operator<(const Node& node) const {return _id < node._id;}
deba@1188
   652
    };
deba@1188
   653
deba@1193
   654
    class RedNode : public Node {
deba@1193
   655
      friend class FullBpGraphBase;
deba@1193
   656
    protected:
deba@1193
   657
deba@1193
   658
      explicit RedNode(int pid) : Node(pid) {}
deba@1193
   659
deba@1193
   660
    public:
deba@1193
   661
      RedNode() {}
deba@1193
   662
      RedNode(const RedNode& node) : Node(node) {}
deba@1193
   663
      RedNode(Invalid) : Node(INVALID){}
deba@1193
   664
    };
deba@1193
   665
deba@1193
   666
    class BlueNode : public Node {
deba@1193
   667
      friend class FullBpGraphBase;
deba@1193
   668
    protected:
deba@1193
   669
deba@1193
   670
      explicit BlueNode(int pid) : Node(pid) {}
deba@1193
   671
deba@1193
   672
    public:
deba@1193
   673
      BlueNode() {}
deba@1193
   674
      BlueNode(const BlueNode& node) : Node(node) {}
deba@1193
   675
      BlueNode(Invalid) : Node(INVALID){}
deba@1193
   676
    };
deba@1193
   677
deba@1188
   678
    class Edge {
deba@1188
   679
      friend class FullBpGraphBase;
deba@1188
   680
    protected:
deba@1188
   681
deba@1188
   682
      int _id;
deba@1188
   683
      explicit Edge(int id) { _id = id;}
deba@1188
   684
deba@1188
   685
    public:
deba@1188
   686
      Edge() {}
deba@1188
   687
      Edge (Invalid) { _id = -1; }
deba@1188
   688
      bool operator==(const Edge& arc) const {return _id == arc._id;}
deba@1188
   689
      bool operator!=(const Edge& arc) const {return _id != arc._id;}
deba@1188
   690
      bool operator<(const Edge& arc) const {return _id < arc._id;}
deba@1188
   691
    };
deba@1188
   692
deba@1188
   693
    class Arc {
deba@1188
   694
      friend class FullBpGraphBase;
deba@1188
   695
    protected:
deba@1188
   696
deba@1188
   697
      int _id;
deba@1188
   698
      explicit Arc(int id) { _id = id;}
deba@1188
   699
deba@1188
   700
    public:
deba@1188
   701
      operator Edge() const {
deba@1188
   702
        return _id != -1 ? edgeFromId(_id / 2) : INVALID;
deba@1188
   703
      }
deba@1188
   704
deba@1188
   705
      Arc() {}
deba@1188
   706
      Arc (Invalid) { _id = -1; }
deba@1188
   707
      bool operator==(const Arc& arc) const {return _id == arc._id;}
deba@1188
   708
      bool operator!=(const Arc& arc) const {return _id != arc._id;}
deba@1188
   709
      bool operator<(const Arc& arc) const {return _id < arc._id;}
deba@1188
   710
    };
deba@1188
   711
deba@1188
   712
deba@1188
   713
  protected:
deba@1188
   714
deba@1188
   715
    FullBpGraphBase()
deba@1188
   716
      : _red_num(0), _blue_num(0), _node_num(0), _edge_num(0) {}
deba@1188
   717
deba@1188
   718
    void construct(int redNum, int blueNum) {
deba@1188
   719
      _red_num = redNum; _blue_num = blueNum;
deba@1188
   720
      _node_num = redNum + blueNum; _edge_num = redNum * blueNum;
deba@1188
   721
    }
deba@1188
   722
deba@1188
   723
  public:
deba@1188
   724
deba@1188
   725
    typedef True NodeNumTag;
deba@1188
   726
    typedef True EdgeNumTag;
deba@1188
   727
    typedef True ArcNumTag;
deba@1188
   728
deba@1188
   729
    int nodeNum() const { return _node_num; }
deba@1188
   730
    int redNum() const { return _red_num; }
deba@1188
   731
    int blueNum() const { return _blue_num; }
deba@1188
   732
    int edgeNum() const { return _edge_num; }
deba@1188
   733
    int arcNum() const { return 2 * _edge_num; }
deba@1188
   734
deba@1188
   735
    int maxNodeId() const { return _node_num - 1; }
deba@1188
   736
    int maxRedId() const { return _red_num - 1; }
deba@1188
   737
    int maxBlueId() const { return _blue_num - 1; }
deba@1188
   738
    int maxEdgeId() const { return _edge_num - 1; }
deba@1188
   739
    int maxArcId() const { return 2 * _edge_num - 1; }
deba@1188
   740
deba@1188
   741
    bool red(Node n) const { return n._id < _red_num; }
deba@1188
   742
    bool blue(Node n) const { return n._id >= _red_num; }
deba@1188
   743
deba@1193
   744
    static RedNode asRedNodeUnsafe(Node n) { return RedNode(n._id); }
deba@1193
   745
    static BlueNode asBlueNodeUnsafe(Node n) { return BlueNode(n._id); }
deba@1193
   746
deba@1188
   747
    Node source(Arc a) const {
deba@1188
   748
      if (a._id & 1) {
deba@1188
   749
        return Node((a._id >> 1) % _red_num);
deba@1188
   750
      } else {
deba@1188
   751
        return Node((a._id >> 1) / _red_num + _red_num);
deba@1188
   752
      }
deba@1188
   753
    }
deba@1188
   754
    Node target(Arc a) const {
deba@1188
   755
      if (a._id & 1) {
deba@1188
   756
        return Node((a._id >> 1) / _red_num + _red_num);
deba@1188
   757
      } else {
deba@1188
   758
        return Node((a._id >> 1) % _red_num);
deba@1188
   759
      }
deba@1188
   760
    }
deba@1188
   761
deba@1193
   762
    RedNode redNode(Edge e) const {
deba@1193
   763
      return RedNode(e._id % _red_num);
deba@1188
   764
    }
deba@1193
   765
    BlueNode blueNode(Edge e) const {
deba@1193
   766
      return BlueNode(e._id / _red_num + _red_num);
deba@1188
   767
    }
deba@1188
   768
deba@1188
   769
    static bool direction(Arc a) {
deba@1188
   770
      return (a._id & 1) == 1;
deba@1188
   771
    }
deba@1188
   772
deba@1188
   773
    static Arc direct(Edge e, bool d) {
deba@1188
   774
      return Arc(e._id * 2 + (d ? 1 : 0));
deba@1188
   775
    }
deba@1188
   776
deba@1188
   777
    void first(Node& node) const {
deba@1188
   778
      node._id = _node_num - 1;
deba@1188
   779
    }
deba@1188
   780
deba@1188
   781
    static void next(Node& node) {
deba@1188
   782
      --node._id;
deba@1188
   783
    }
deba@1188
   784
deba@1193
   785
    void first(RedNode& node) const {
deba@1188
   786
      node._id = _red_num - 1;
deba@1188
   787
    }
deba@1188
   788
deba@1193
   789
    static void next(RedNode& node) {
deba@1188
   790
      --node._id;
deba@1188
   791
    }
deba@1188
   792
deba@1193
   793
    void first(BlueNode& node) const {
deba@1188
   794
      if (_red_num == _node_num) node._id = -1;
deba@1188
   795
      else node._id = _node_num - 1;
deba@1188
   796
    }
deba@1188
   797
deba@1193
   798
    void next(BlueNode& node) const {
deba@1188
   799
      if (node._id == _red_num) node._id = -1;
deba@1188
   800
      else --node._id;
deba@1188
   801
    }
deba@1188
   802
deba@1188
   803
    void first(Arc& arc) const {
deba@1188
   804
      arc._id = 2 * _edge_num - 1;
deba@1188
   805
    }
deba@1188
   806
deba@1188
   807
    static void next(Arc& arc) {
deba@1188
   808
      --arc._id;
deba@1188
   809
    }
deba@1188
   810
deba@1188
   811
    void first(Edge& arc) const {
deba@1188
   812
      arc._id = _edge_num - 1;
deba@1188
   813
    }
deba@1188
   814
deba@1188
   815
    static void next(Edge& arc) {
deba@1188
   816
      --arc._id;
deba@1188
   817
    }
deba@1188
   818
deba@1188
   819
    void firstOut(Arc &a, const Node& v) const {
deba@1188
   820
      if (v._id < _red_num) {
deba@1188
   821
        a._id = 2 * (v._id + _red_num * (_blue_num - 1)) + 1;
deba@1188
   822
      } else {
deba@1188
   823
        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num));
deba@1188
   824
      }
deba@1188
   825
    }
deba@1188
   826
    void nextOut(Arc &a) const {
deba@1188
   827
      if (a._id & 1) {
deba@1188
   828
        a._id -= 2 * _red_num;
deba@1188
   829
        if (a._id < 0) a._id = -1;
deba@1188
   830
      } else {
deba@1188
   831
        if (a._id % (2 * _red_num) == 0) a._id = -1;
deba@1188
   832
        else a._id -= 2;
deba@1188
   833
      }
deba@1188
   834
    }
deba@1188
   835
deba@1188
   836
    void firstIn(Arc &a, const Node& v) const {
deba@1188
   837
      if (v._id < _red_num) {
deba@1188
   838
        a._id = 2 * (v._id + _red_num * (_blue_num - 1));
deba@1188
   839
      } else {
deba@1188
   840
        a._id = 2 * (_red_num - 1 + _red_num * (v._id - _red_num)) + 1;
deba@1188
   841
      }
deba@1188
   842
    }
deba@1188
   843
    void nextIn(Arc &a) const {
deba@1188
   844
      if (a._id & 1) {
deba@1188
   845
        if (a._id % (2 * _red_num) == 1) a._id = -1;
deba@1188
   846
        else a._id -= 2;
deba@1188
   847
      } else {
deba@1188
   848
        a._id -= 2 * _red_num;
deba@1188
   849
        if (a._id < 0) a._id = -1;
deba@1188
   850
      }
deba@1188
   851
    }
deba@1188
   852
deba@1188
   853
    void firstInc(Edge &e, bool& d, const Node& v) const {
deba@1188
   854
      if (v._id < _red_num) {
deba@1188
   855
        d = true;
deba@1188
   856
        e._id = v._id + _red_num * (_blue_num - 1);
deba@1188
   857
      } else {
deba@1188
   858
        d = false;
deba@1188
   859
        e._id = _red_num - 1 + _red_num * (v._id - _red_num);
deba@1188
   860
      }
deba@1188
   861
    }
deba@1188
   862
    void nextInc(Edge &e, bool& d) const {
deba@1188
   863
      if (d) {
deba@1188
   864
        e._id -= _red_num;
deba@1188
   865
        if (e._id < 0) e._id = -1;
deba@1188
   866
      } else {
deba@1188
   867
        if (e._id % _red_num == 0) e._id = -1;
deba@1188
   868
        else --e._id;
deba@1188
   869
      }
deba@1188
   870
    }
deba@1188
   871
deba@1193
   872
    static int id(const Node& v) { return v._id; }
deba@1193
   873
    int id(const RedNode& v) const { return v._id; }
deba@1193
   874
    int id(const BlueNode& v) const { return v._id - _red_num; }
deba@1188
   875
    static int id(Arc e) { return e._id; }
deba@1188
   876
    static int id(Edge e) { return e._id; }
alpar@1270
   877
deba@1188
   878
    static Node nodeFromId(int id) { return Node(id);}
deba@1188
   879
    static Arc arcFromId(int id) { return Arc(id);}
deba@1188
   880
    static Edge edgeFromId(int id) { return Edge(id);}
deba@1188
   881
deba@1188
   882
    bool valid(Node n) const {
deba@1188
   883
      return n._id >= 0 && n._id < _node_num;
deba@1188
   884
    }
deba@1188
   885
    bool valid(Arc a) const {
deba@1188
   886
      return a._id >= 0 && a._id < 2 * _edge_num;
deba@1188
   887
    }
deba@1188
   888
    bool valid(Edge e) const {
deba@1188
   889
      return e._id >= 0 && e._id < _edge_num;
deba@1188
   890
    }
deba@1188
   891
deba@1193
   892
    RedNode redNode(int index) const {
deba@1193
   893
      return RedNode(index);
deba@1188
   894
    }
deba@1188
   895
deba@1193
   896
    int index(RedNode n) const {
deba@1188
   897
      return n._id;
deba@1188
   898
    }
deba@1188
   899
deba@1193
   900
    BlueNode blueNode(int index) const {
deba@1193
   901
      return BlueNode(index + _red_num);
deba@1188
   902
    }
deba@1188
   903
deba@1193
   904
    int index(BlueNode n) const {
deba@1188
   905
      return n._id - _red_num;
deba@1188
   906
    }
alpar@1270
   907
deba@1188
   908
    void clear() {
deba@1188
   909
      _red_num = 0; _blue_num = 0;
deba@1188
   910
      _node_num = 0; _edge_num = 0;
deba@1188
   911
    }
deba@1188
   912
alpar@1270
   913
    Edge edge(const Node& u, const Node& v) const {
deba@1188
   914
      if (u._id < _red_num) {
deba@1188
   915
        if (v._id < _red_num) {
deba@1188
   916
          return Edge(-1);
deba@1188
   917
        } else {
deba@1188
   918
          return Edge(u._id + _red_num * (v._id - _red_num));
deba@1188
   919
        }
deba@1188
   920
      } else {
deba@1188
   921
        if (v._id < _red_num) {
deba@1188
   922
          return Edge(v._id + _red_num * (u._id - _red_num));
deba@1188
   923
        } else {
deba@1188
   924
          return Edge(-1);
deba@1188
   925
        }
deba@1188
   926
      }
deba@1188
   927
    }
deba@1188
   928
alpar@1270
   929
    Arc arc(const Node& u, const Node& v) const {
deba@1188
   930
      if (u._id < _red_num) {
deba@1188
   931
        if (v._id < _red_num) {
deba@1188
   932
          return Arc(-1);
deba@1188
   933
        } else {
deba@1188
   934
          return Arc(2 * (u._id + _red_num * (v._id - _red_num)) + 1);
deba@1188
   935
        }
deba@1188
   936
      } else {
deba@1188
   937
        if (v._id < _red_num) {
deba@1188
   938
          return Arc(2 * (v._id + _red_num * (u._id - _red_num)));
deba@1188
   939
        } else {
deba@1188
   940
          return Arc(-1);
deba@1188
   941
        }
deba@1188
   942
      }
deba@1188
   943
    }
deba@1188
   944
deba@1188
   945
    typedef True FindEdgeTag;
deba@1188
   946
    typedef True FindArcTag;
deba@1188
   947
deba@1188
   948
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@1188
   949
      return prev != INVALID ? INVALID : edge(u, v);
deba@1188
   950
    }
deba@1188
   951
deba@1188
   952
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
deba@1188
   953
      return prev != INVALID ? INVALID : arc(s, t);
deba@1188
   954
    }
deba@1188
   955
deba@1188
   956
  };
deba@1188
   957
deba@1188
   958
  typedef BpGraphExtender<FullBpGraphBase> ExtendedFullBpGraphBase;
deba@1188
   959
deba@1188
   960
  /// \ingroup graphs
deba@1188
   961
  ///
deba@1188
   962
  /// \brief An undirected full bipartite graph class.
deba@1188
   963
  ///
deba@1188
   964
  /// FullBpGraph is a simple and fast implmenetation of undirected
deba@1188
   965
  /// full bipartite graphs. It contains an edge between every
deba@1188
   966
  /// red-blue pairs of nodes, therefore the number of edges is
deba@1188
   967
  /// <tt>nr*nb</tt>.  This class is completely static and it needs
deba@1188
   968
  /// constant memory space.  Thus you can neither add nor delete
deba@1188
   969
  /// nodes or edges, however the structure can be resized using
deba@1188
   970
  /// resize().
deba@1188
   971
  ///
deba@1188
   972
  /// This type fully conforms to the \ref concepts::BpGraph "BpGraph concept".
deba@1188
   973
  /// Most of its member functions and nested classes are documented
deba@1188
   974
  /// only in the concept class.
deba@1188
   975
  ///
deba@1188
   976
  /// This class provides constant time counting for nodes, edges and arcs.
deba@1188
   977
  ///
deba@1188
   978
  /// \sa FullGraph
deba@1188
   979
  class FullBpGraph : public ExtendedFullBpGraphBase {
deba@1188
   980
  public:
deba@1188
   981
deba@1188
   982
    typedef ExtendedFullBpGraphBase Parent;
deba@1188
   983
deba@1188
   984
    /// \brief Default constructor.
deba@1188
   985
    ///
deba@1188
   986
    /// Default constructor. The number of nodes and edges will be zero.
deba@1188
   987
    FullBpGraph() { construct(0, 0); }
deba@1188
   988
deba@1188
   989
    /// \brief Constructor
deba@1188
   990
    ///
deba@1188
   991
    /// Constructor.
deba@1188
   992
    /// \param redNum The number of the red nodes.
deba@1188
   993
    /// \param blueNum The number of the blue nodes.
deba@1188
   994
    FullBpGraph(int redNum, int blueNum) { construct(redNum, blueNum); }
deba@1188
   995
deba@1188
   996
    /// \brief Resizes the graph
deba@1188
   997
    ///
deba@1188
   998
    /// This function resizes the graph. It fully destroys and
deba@1188
   999
    /// rebuilds the structure, therefore the maps of the graph will be
deba@1188
  1000
    /// reallocated automatically and the previous values will be lost.
deba@1188
  1001
    void resize(int redNum, int blueNum) {
deba@1188
  1002
      Parent::notifier(Arc()).clear();
deba@1188
  1003
      Parent::notifier(Edge()).clear();
deba@1188
  1004
      Parent::notifier(Node()).clear();
deba@1188
  1005
      Parent::notifier(BlueNode()).clear();
deba@1188
  1006
      Parent::notifier(RedNode()).clear();
deba@1188
  1007
      construct(redNum, blueNum);
deba@1188
  1008
      Parent::notifier(RedNode()).build();
deba@1188
  1009
      Parent::notifier(BlueNode()).build();
deba@1188
  1010
      Parent::notifier(Node()).build();
deba@1188
  1011
      Parent::notifier(Edge()).build();
deba@1188
  1012
      Parent::notifier(Arc()).build();
deba@1188
  1013
    }
deba@1188
  1014
deba@1192
  1015
    using Parent::redNode;
deba@1192
  1016
    using Parent::blueNode;
deba@1192
  1017
deba@1188
  1018
    /// \brief Returns the red node with the given index.
deba@1188
  1019
    ///
deba@1188
  1020
    /// Returns the red node with the given index. Since this
deba@1188
  1021
    /// structure is completely static, the red nodes can be indexed
deba@1188
  1022
    /// with integers from the range <tt>[0..redNum()-1]</tt>.
deba@1188
  1023
    /// \sa redIndex()
deba@1193
  1024
    RedNode redNode(int index) const { return Parent::redNode(index); }
deba@1188
  1025
deba@1188
  1026
    /// \brief Returns the index of the given red node.
deba@1188
  1027
    ///
deba@1188
  1028
    /// Returns the index of the given red node. Since this structure
deba@1188
  1029
    /// is completely static, the red nodes can be indexed with
deba@1188
  1030
    /// integers from the range <tt>[0..redNum()-1]</tt>.
deba@1188
  1031
    ///
deba@1188
  1032
    /// \sa operator()()
deba@1193
  1033
    int index(RedNode node) const { return Parent::index(node); }
deba@1188
  1034
deba@1188
  1035
    /// \brief Returns the blue node with the given index.
deba@1188
  1036
    ///
deba@1188
  1037
    /// Returns the blue node with the given index. Since this
deba@1188
  1038
    /// structure is completely static, the blue nodes can be indexed
deba@1188
  1039
    /// with integers from the range <tt>[0..blueNum()-1]</tt>.
deba@1188
  1040
    /// \sa blueIndex()
deba@1193
  1041
    BlueNode blueNode(int index) const { return Parent::blueNode(index); }
deba@1188
  1042
deba@1188
  1043
    /// \brief Returns the index of the given blue node.
deba@1188
  1044
    ///
deba@1188
  1045
    /// Returns the index of the given blue node. Since this structure
deba@1188
  1046
    /// is completely static, the blue nodes can be indexed with
deba@1188
  1047
    /// integers from the range <tt>[0..blueNum()-1]</tt>.
deba@1188
  1048
    ///
deba@1188
  1049
    /// \sa operator()()
deba@1193
  1050
    int index(BlueNode node) const { return Parent::index(node); }
deba@1188
  1051
deba@1188
  1052
    /// \brief Returns the edge which connects the given nodes.
deba@1188
  1053
    ///
deba@1188
  1054
    /// Returns the edge which connects the given nodes.
deba@1188
  1055
    Edge edge(const Node& u, const Node& v) const {
deba@1188
  1056
      return Parent::edge(u, v);
deba@1188
  1057
    }
deba@1188
  1058
deba@1188
  1059
    /// \brief Returns the arc which connects the given nodes.
deba@1188
  1060
    ///
deba@1188
  1061
    /// Returns the arc which connects the given nodes.
deba@1188
  1062
    Arc arc(const Node& u, const Node& v) const {
deba@1188
  1063
      return Parent::arc(u, v);
deba@1188
  1064
    }
deba@1188
  1065
deba@1188
  1066
    /// \brief Number of nodes.
deba@1188
  1067
    int nodeNum() const { return Parent::nodeNum(); }
deba@1188
  1068
    /// \brief Number of red nodes.
deba@1188
  1069
    int redNum() const { return Parent::redNum(); }
deba@1188
  1070
    /// \brief Number of blue nodes.
deba@1188
  1071
    int blueNum() const { return Parent::blueNum(); }
deba@1188
  1072
    /// \brief Number of arcs.
deba@1188
  1073
    int arcNum() const { return Parent::arcNum(); }
deba@1188
  1074
    /// \brief Number of edges.
deba@1188
  1075
    int edgeNum() const { return Parent::edgeNum(); }
deba@1188
  1076
  };
deba@1188
  1077
deba@365
  1078
deba@365
  1079
} //namespace lemon
deba@365
  1080
deba@365
  1081
deba@365
  1082
#endif //LEMON_FULL_GRAPH_H