lemon/full_graph.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 14 Aug 2008 21:49:39 +0200
changeset 365 37557a46e298
child 366 80a4d0742e98
permissions -rw-r--r--
Porting full graphs from svn 3498

- the FullGraph is redesigned in implementation
- some improvemnts in documentation
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
 *
deba@365
     5
 * Copyright (C) 2003-2008
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/math.h>
deba@365
    23
deba@365
    24
#include <lemon/core.h>
deba@365
    25
#include <lemon/bits/graph_extender.h>
deba@365
    26
deba@365
    27
///\ingroup graphs
deba@365
    28
///\file
deba@365
    29
///\brief FullDigraph and FullGraph classes.
deba@365
    30
namespace lemon {
deba@365
    31
deba@365
    32
  class FullDigraphBase {
deba@365
    33
  public:
deba@365
    34
deba@365
    35
    typedef FullDigraphBase Graph;
deba@365
    36
deba@365
    37
    class Node;
deba@365
    38
    class Arc;
deba@365
    39
deba@365
    40
  protected:
deba@365
    41
deba@365
    42
    int _node_num;
deba@365
    43
    int _arc_num;
deba@365
    44
deba@365
    45
    FullDigraphBase() {}
deba@365
    46
deba@365
    47
    void construct(int n) { _node_num = n; _arc_num = n * n; }
deba@365
    48
deba@365
    49
  public:
deba@365
    50
deba@365
    51
    typedef True NodeNumTag;
deba@365
    52
    typedef True ArcNumTag;
deba@365
    53
deba@365
    54
    Node operator()(int ix) const { return Node(ix); }
deba@365
    55
    int index(const Node& node) const { return node._id; }
deba@365
    56
deba@365
    57
    Arc arc(const Node& s, const Node& t) const {
deba@365
    58
      return Arc(s._id * _node_num + t._id);
deba@365
    59
    }
deba@365
    60
deba@365
    61
    int nodeNum() const { return _node_num; }
deba@365
    62
    int arcNum() const { return _arc_num; }
deba@365
    63
deba@365
    64
    int maxNodeId() const { return _node_num - 1; }
deba@365
    65
    int maxArcId() const { return _arc_num - 1; }
deba@365
    66
deba@365
    67
    Node source(Arc arc) const { return arc._id / _node_num; }
deba@365
    68
    Node target(Arc arc) const { return arc._id % _node_num; }
deba@365
    69
deba@365
    70
deba@365
    71
    static int id(Node node) { return node._id; }
deba@365
    72
    static int id(Arc arc) { return arc._id; }
deba@365
    73
deba@365
    74
    static Node nodeFromId(int id) { return Node(id);}
deba@365
    75
deba@365
    76
    static Arc arcFromId(int id) { return Arc(id);}
deba@365
    77
deba@365
    78
    typedef True FindArcTag;
deba@365
    79
deba@365
    80
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
deba@365
    81
      return prev != INVALID ? arc(s, t) : INVALID;
deba@365
    82
    }
deba@365
    83
deba@365
    84
deba@365
    85
    class Node {
deba@365
    86
      friend class FullDigraphBase;
deba@365
    87
deba@365
    88
    protected:
deba@365
    89
      int _id;
deba@365
    90
      Node(int id) : _id(id) {}
deba@365
    91
    public:
deba@365
    92
      Node() {}
deba@365
    93
      Node (Invalid) : _id(-1) {}
deba@365
    94
      bool operator==(const Node node) const {return _id == node._id;}
deba@365
    95
      bool operator!=(const Node node) const {return _id != node._id;}
deba@365
    96
      bool operator<(const Node node) const {return _id < node._id;}
deba@365
    97
    };
deba@365
    98
deba@365
    99
    class Arc {
deba@365
   100
      friend class FullDigraphBase;
deba@365
   101
deba@365
   102
    protected:
deba@365
   103
      int _id;  // _node_num * source + target;
deba@365
   104
deba@365
   105
      Arc(int id) : _id(id) {}
deba@365
   106
deba@365
   107
    public:
deba@365
   108
      Arc() { }
deba@365
   109
      Arc (Invalid) { _id = -1; }
deba@365
   110
      bool operator==(const Arc arc) const {return _id == arc._id;}
deba@365
   111
      bool operator!=(const Arc arc) const {return _id != arc._id;}
deba@365
   112
      bool operator<(const Arc arc) const {return _id < arc._id;}
deba@365
   113
    };
deba@365
   114
deba@365
   115
    void first(Node& node) const {
deba@365
   116
      node._id = _node_num - 1;
deba@365
   117
    }
deba@365
   118
deba@365
   119
    static void next(Node& node) {
deba@365
   120
      --node._id;
deba@365
   121
    }
deba@365
   122
deba@365
   123
    void first(Arc& arc) const {
deba@365
   124
      arc._id = _arc_num - 1;
deba@365
   125
    }
deba@365
   126
deba@365
   127
    static void next(Arc& arc) {
deba@365
   128
      --arc._id;
deba@365
   129
    }
deba@365
   130
deba@365
   131
    void firstOut(Arc& arc, const Node& node) const {
deba@365
   132
      arc._id = (node._id + 1) * _node_num - 1;
deba@365
   133
    }
deba@365
   134
deba@365
   135
    void nextOut(Arc& arc) const {
deba@365
   136
      if (arc._id % _node_num == 0) arc._id = 0;
deba@365
   137
      --arc._id;
deba@365
   138
    }
deba@365
   139
deba@365
   140
    void firstIn(Arc& arc, const Node& node) const {
deba@365
   141
      arc._id = _arc_num + node._id - _node_num;
deba@365
   142
    }
deba@365
   143
deba@365
   144
    void nextIn(Arc& arc) const {
deba@365
   145
      arc._id -= _node_num;
deba@365
   146
      if (arc._id < 0) arc._id = -1;
deba@365
   147
    }
deba@365
   148
deba@365
   149
  };
deba@365
   150
deba@365
   151
  typedef DigraphExtender<FullDigraphBase> ExtendedFullDigraphBase;
deba@365
   152
deba@365
   153
  /// \ingroup graphs
deba@365
   154
  ///
deba@365
   155
  /// \brief A full digraph class.
deba@365
   156
  ///
deba@365
   157
  /// This is a simple and fast directed full graph implementation.
deba@365
   158
  /// From each node go arcs to each node (including the source node),
deba@365
   159
  /// therefore the number of the arcs in the digraph is the square of
deba@365
   160
  /// the node number. The digraph is completely static, so you can
deba@365
   161
  /// neither add nor delete either arcs or nodes, and it needs just
deba@365
   162
  /// constant space in memory.
deba@365
   163
  ///
deba@365
   164
  /// Thus it conforms to the \ref concepts::Digraph "Digraph" concept
deba@365
   165
  /// and it also has an important extra feature that its maps are
deba@365
   166
  /// real \ref concepts::ReferenceMap "reference map"s.
deba@365
   167
  /// \sa concepts::Digraph.
deba@365
   168
  ///
deba@365
   169
  /// \sa FullGraph
deba@365
   170
  class FullDigraph : public ExtendedFullDigraphBase {
deba@365
   171
  public:
deba@365
   172
deba@365
   173
    typedef ExtendedFullDigraphBase Parent;
deba@365
   174
deba@365
   175
    /// \brief Constructor
deba@365
   176
    FullDigraph() { construct(0); }
deba@365
   177
deba@365
   178
    /// \brief Constructor
deba@365
   179
    ///
deba@365
   180
    /// \param n The number of the nodes.
deba@365
   181
    FullDigraph(int n) { construct(n); }
deba@365
   182
deba@365
   183
    /// \brief Resize the digraph
deba@365
   184
    ///
deba@365
   185
    /// Resize the digraph. The function will fully destroy and
deba@365
   186
    /// rebuild the digraph.  This cause that the maps of the digraph
deba@365
   187
    /// will reallocated automatically and the previous values will be
deba@365
   188
    /// lost.
deba@365
   189
    void resize(int n) {
deba@365
   190
      Parent::notifier(Arc()).clear();
deba@365
   191
      Parent::notifier(Node()).clear();
deba@365
   192
      construct(n);
deba@365
   193
      Parent::notifier(Node()).build();
deba@365
   194
      Parent::notifier(Arc()).build();
deba@365
   195
    }
deba@365
   196
deba@365
   197
    /// \brief Returns the node with the given index.
deba@365
   198
    ///
deba@365
   199
    /// Returns the node with the given index. Because it is a
deba@365
   200
    /// static size digraph the node's of the digraph can be indexed
deba@365
   201
    /// in the range <tt>[0..nodeNum()-1]</tt> and the index of
deba@365
   202
    /// the node can accessed by the \e index() member.
deba@365
   203
    Node operator()(int ix) const { return Parent::operator()(ix); }
deba@365
   204
deba@365
   205
    /// \brief Returns the index of the node.
deba@365
   206
    ///
deba@365
   207
    /// Returns the index of the node. Because it is a
deba@365
   208
    /// static size digraph the node's of the digraph can be indexed
deba@365
   209
    /// in the range <tt>[0..nodeNum()-1]</tt> and the index of
deba@365
   210
    /// the node can accessed by the \e index() member.
deba@365
   211
    int index(const Node& node) const { return Parent::index(node); }
deba@365
   212
deba@365
   213
    /// \brief Returns the arc connects the given nodes.
deba@365
   214
    ///
deba@365
   215
    /// Returns the arc connects the given nodes.
deba@365
   216
    Arc arc(const Node& u, const Node& v) const {
deba@365
   217
      return Parent::arc(u, v);
deba@365
   218
    }
deba@365
   219
deba@365
   220
    /// \brief Number of nodes.
deba@365
   221
    int nodeNum() const { return Parent::nodeNum(); }
deba@365
   222
    /// \brief Number of arcs.
deba@365
   223
    int arcNum() const { return Parent::arcNum(); }
deba@365
   224
  };
deba@365
   225
deba@365
   226
deba@365
   227
  class FullGraphBase {
deba@365
   228
    int _node_num;
deba@365
   229
    int _edge_num;
deba@365
   230
  public:
deba@365
   231
deba@365
   232
    typedef FullGraphBase Graph;
deba@365
   233
deba@365
   234
    class Node;
deba@365
   235
    class Arc;
deba@365
   236
    class Edge;
deba@365
   237
deba@365
   238
  protected:
deba@365
   239
deba@365
   240
    FullGraphBase() {}
deba@365
   241
deba@365
   242
    void construct(int n) { _node_num = n; _edge_num = n * (n - 1) / 2; }
deba@365
   243
deba@365
   244
    int _uid(int e) const {
deba@365
   245
      int u = e / _node_num;
deba@365
   246
      int v = e % _node_num;
deba@365
   247
      return u < v ? u : _node_num - 2 - u;
deba@365
   248
    }
deba@365
   249
deba@365
   250
    int _vid(int e) const {
deba@365
   251
      int u = e / _node_num;
deba@365
   252
      int v = e % _node_num;
deba@365
   253
      return u < v ? v : _node_num - 1 - v;
deba@365
   254
    }
deba@365
   255
deba@365
   256
    void _uvid(int e, int& u, int& v) const {
deba@365
   257
      u = e / _node_num;
deba@365
   258
      v = e % _node_num;
deba@365
   259
      if  (u >= v) {
deba@365
   260
        u = _node_num - 2 - u;
deba@365
   261
        v = _node_num - 1 - v;
deba@365
   262
      }
deba@365
   263
    }
deba@365
   264
deba@365
   265
    void _stid(int a, int& s, int& t) const {
deba@365
   266
      if ((a & 1) == 1) {
deba@365
   267
        _uvid(a >> 1, s, t);
deba@365
   268
      } else {
deba@365
   269
        _uvid(a >> 1, t, s);
deba@365
   270
      }
deba@365
   271
    }
deba@365
   272
deba@365
   273
    int _eid(int u, int v) const {
deba@365
   274
      if (u < (_node_num - 1) / 2) {
deba@365
   275
        return u * _node_num + v;
deba@365
   276
      } else {
deba@365
   277
        return (_node_num - 1 - u) * _node_num - v - 1;
deba@365
   278
      }
deba@365
   279
    }
deba@365
   280
deba@365
   281
  public:
deba@365
   282
deba@365
   283
deba@365
   284
    Node operator()(int ix) const { return Node(ix); }
deba@365
   285
    int index(const Node& node) const { return node._id; }
deba@365
   286
deba@365
   287
    Edge edge(const Node& u, const Node& v) const {
deba@365
   288
      if (u._id < v._id) {
deba@365
   289
        return Edge(_eid(u._id, v._id));
deba@365
   290
      } else if (u._id != v._id) {
deba@365
   291
        return Edge(_eid(v._id, u._id));
deba@365
   292
      } else {
deba@365
   293
        return INVALID;
deba@365
   294
      }
deba@365
   295
    }
deba@365
   296
deba@365
   297
    Arc arc(const Node& s, const Node& t) const {
deba@365
   298
      if (s._id < t._id) {
deba@365
   299
        return Arc((_eid(s._id, t._id) << 1) | 1);
deba@365
   300
      } else if (s._id != t._id) {
deba@365
   301
        return Arc(_eid(t._id, s._id) << 1);
deba@365
   302
      } else {
deba@365
   303
        return INVALID;
deba@365
   304
      }
deba@365
   305
    }
deba@365
   306
deba@365
   307
    typedef True NodeNumTag;
deba@365
   308
    typedef True EdgeNumTag;
deba@365
   309
deba@365
   310
    int nodeNum() const { return _node_num; }
deba@365
   311
    int arcNum() const { return 2 * _edge_num; }
deba@365
   312
    int edgeNum() const { return _edge_num; }
deba@365
   313
deba@365
   314
    static int id(Node node) { return node._id; }
deba@365
   315
    static int id(Arc arc) { return arc._id; }
deba@365
   316
    static int id(Edge edge) { return edge._id; }
deba@365
   317
deba@365
   318
    int maxNodeId() const { return _node_num-1; }
deba@365
   319
    int maxArcId() const { return 2 * _edge_num-1; }
deba@365
   320
    int maxEdgeId() const { return _edge_num-1; }
deba@365
   321
deba@365
   322
    static Node nodeFromId(int id) { return Node(id);}
deba@365
   323
    static Arc arcFromId(int id) { return Arc(id);}
deba@365
   324
    static Edge edgeFromId(int id) { return Edge(id);}
deba@365
   325
deba@365
   326
    Node u(Edge edge) const {
deba@365
   327
      return Node(_uid(edge._id));
deba@365
   328
    }
deba@365
   329
deba@365
   330
    Node v(Edge edge) const {
deba@365
   331
      return Node(_vid(edge._id));
deba@365
   332
    }
deba@365
   333
deba@365
   334
    Node source(Arc arc) const {
deba@365
   335
      return Node((arc._id & 1) == 1 ?
deba@365
   336
                  _uid(arc._id >> 1) : _vid(arc._id >> 1));
deba@365
   337
    }
deba@365
   338
deba@365
   339
    Node target(Arc arc) const {
deba@365
   340
      return Node((arc._id & 1) == 1 ?
deba@365
   341
                  _vid(arc._id >> 1) : _uid(arc._id >> 1));
deba@365
   342
    }
deba@365
   343
deba@365
   344
    typedef True FindEdgeTag;
deba@365
   345
deba@365
   346
    Edge findEdge(Node u, Node v, Edge prev = INVALID) const {
deba@365
   347
      return prev != INVALID ? INVALID : edge(u, v);
deba@365
   348
    }
deba@365
   349
deba@365
   350
    Arc findArc(Node s, Node t, Arc prev = INVALID) const {
deba@365
   351
      return prev != INVALID ? INVALID : arc(s, t);
deba@365
   352
    }
deba@365
   353
deba@365
   354
    class Node {
deba@365
   355
      friend class FullGraphBase;
deba@365
   356
deba@365
   357
    protected:
deba@365
   358
      int _id;
deba@365
   359
      Node(int id) : _id(id) {}
deba@365
   360
    public:
deba@365
   361
      Node() {}
deba@365
   362
      Node (Invalid) { _id = -1; }
deba@365
   363
      bool operator==(const Node node) const {return _id == node._id;}
deba@365
   364
      bool operator!=(const Node node) const {return _id != node._id;}
deba@365
   365
      bool operator<(const Node node) const {return _id < node._id;}
deba@365
   366
    };
deba@365
   367
deba@365
   368
    class Edge {
deba@365
   369
      friend class FullGraphBase;
deba@365
   370
deba@365
   371
    protected:
deba@365
   372
      int _id;
deba@365
   373
deba@365
   374
      Edge(int id) : _id(id) {}
deba@365
   375
deba@365
   376
    public:
deba@365
   377
      Edge() { }
deba@365
   378
      Edge (Invalid) { _id = -1; }
deba@365
   379
deba@365
   380
      bool operator==(const Edge edge) const {return _id == edge._id;}
deba@365
   381
      bool operator!=(const Edge edge) const {return _id != edge._id;}
deba@365
   382
      bool operator<(const Edge edge) const {return _id < edge._id;}
deba@365
   383
    };
deba@365
   384
deba@365
   385
    class Arc {
deba@365
   386
      friend class FullGraphBase;
deba@365
   387
deba@365
   388
    protected:
deba@365
   389
      int _id;
deba@365
   390
deba@365
   391
      Arc(int id) : _id(id) {}
deba@365
   392
deba@365
   393
    public:
deba@365
   394
      Arc() { }
deba@365
   395
      Arc (Invalid) { _id = -1; }
deba@365
   396
deba@365
   397
      operator Edge() const { return Edge(_id != -1 ? (_id >> 1) : -1); }
deba@365
   398
deba@365
   399
      bool operator==(const Arc arc) const {return _id == arc._id;}
deba@365
   400
      bool operator!=(const Arc arc) const {return _id != arc._id;}
deba@365
   401
      bool operator<(const Arc arc) const {return _id < arc._id;}
deba@365
   402
    };
deba@365
   403
deba@365
   404
    static bool direction(Arc arc) {
deba@365
   405
      return (arc._id & 1) == 1;
deba@365
   406
    }
deba@365
   407
deba@365
   408
    static Arc direct(Edge edge, bool dir) {
deba@365
   409
      return Arc((edge._id << 1) | (dir ? 1 : 0));
deba@365
   410
    }
deba@365
   411
deba@365
   412
    void first(Node& node) const {
deba@365
   413
      node._id = _node_num - 1;
deba@365
   414
    }
deba@365
   415
deba@365
   416
    static void next(Node& node) {
deba@365
   417
      --node._id;
deba@365
   418
    }
deba@365
   419
deba@365
   420
    void first(Arc& arc) const {
deba@365
   421
      arc._id = (_edge_num << 1) - 1;
deba@365
   422
    }
deba@365
   423
deba@365
   424
    static void next(Arc& arc) {
deba@365
   425
      --arc._id;
deba@365
   426
    }
deba@365
   427
deba@365
   428
    void first(Edge& edge) const {
deba@365
   429
      edge._id = _edge_num - 1;
deba@365
   430
    }
deba@365
   431
deba@365
   432
    static void next(Edge& edge) {
deba@365
   433
      --edge._id;
deba@365
   434
    }
deba@365
   435
deba@365
   436
    void firstOut(Arc& arc, const Node& node) const {
deba@365
   437
      int s = node._id, t = _node_num - 1;
deba@365
   438
      if (s < t) {
deba@365
   439
        arc._id = (_eid(s, t) << 1) | 1;
deba@365
   440
      } else {
deba@365
   441
        --t;
deba@365
   442
        arc._id = (t != -1 ? (_eid(t, s) << 1) : -1);
deba@365
   443
      }
deba@365
   444
    }
deba@365
   445
deba@365
   446
    void nextOut(Arc& arc) const {
deba@365
   447
      int s, t;
deba@365
   448
      _stid(arc._id, s, t);
deba@365
   449
      --t;
deba@365
   450
      if (s < t) {
deba@365
   451
        arc._id = (_eid(s, t) << 1) | 1;
deba@365
   452
      } else {
deba@365
   453
        if (s == t) --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 firstIn(Arc& arc, const Node& node) const {
deba@365
   459
      int s = _node_num - 1, t = node._id;
deba@365
   460
      if (s > t) {
deba@365
   461
        arc._id = (_eid(t, s) << 1);
deba@365
   462
      } else {
deba@365
   463
        --s;
deba@365
   464
        arc._id = (s != -1 ? (_eid(s, t) << 1) | 1 : -1);
deba@365
   465
      }
deba@365
   466
    }
deba@365
   467
deba@365
   468
    void nextIn(Arc& arc) const {
deba@365
   469
      int s, t;
deba@365
   470
      _stid(arc._id, s, t);
deba@365
   471
      --s;
deba@365
   472
      if (s > t) {
deba@365
   473
        arc._id = (_eid(t, s) << 1);
deba@365
   474
      } else {
deba@365
   475
        if (s == t) --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 firstInc(Edge& edge, bool& dir, const Node& node) const {
deba@365
   481
      int u = node._id, v = _node_num - 1;
deba@365
   482
      if (u < v) {
deba@365
   483
        edge._id = _eid(u, v);
deba@365
   484
        dir = true;
deba@365
   485
      } else {
deba@365
   486
        --v;
deba@365
   487
        edge._id = (v != -1 ? _eid(v, u) : -1);
deba@365
   488
        dir = false;
deba@365
   489
      }
deba@365
   490
    }
deba@365
   491
deba@365
   492
    void nextInc(Edge& edge, bool& dir) const {
deba@365
   493
      int u, v;
deba@365
   494
      if (dir) {
deba@365
   495
        _uvid(edge._id, u, v);
deba@365
   496
        --v;
deba@365
   497
        if (u < v) {
deba@365
   498
          edge._id = _eid(u, v);
deba@365
   499
        } else {
deba@365
   500
          --v;
deba@365
   501
          edge._id = (v != -1 ? _eid(v, u) : -1);
deba@365
   502
          dir = false;
deba@365
   503
        }
deba@365
   504
      } else {
deba@365
   505
        _uvid(edge._id, v, u);
deba@365
   506
        --v;
deba@365
   507
        edge._id = (v != -1 ? _eid(v, u) : -1);
deba@365
   508
      }
deba@365
   509
    }
deba@365
   510
deba@365
   511
  };
deba@365
   512
deba@365
   513
  typedef GraphExtender<FullGraphBase> ExtendedFullGraphBase;
deba@365
   514
deba@365
   515
  /// \ingroup graphs
deba@365
   516
  ///
deba@365
   517
  /// \brief An undirected full graph class.
deba@365
   518
  ///
deba@365
   519
  /// This is a simple and fast undirected full graph
deba@365
   520
  /// implementation. From each node go edge to each other node,
deba@365
   521
  /// therefore the number of edges in the graph is
deba@365
   522
  /// <tt>n(n-1)/2</tt>. It is completely static, so you can neither
deba@365
   523
  /// add nor delete either edges or nodes, and it needs just constant
deba@365
   524
  /// space in memory.
deba@365
   525
  ///
deba@365
   526
  /// The \e FullDigraph and \e FullGraph classes are very similar,
deba@365
   527
  /// but there are two differences. While the \e FullDigraph class is
deba@365
   528
  /// conform just to the \ref concepts::Digraph "Digraph" concept,
deba@365
   529
  /// this class is conform to the \ref concepts::Graph "Graph"
deba@365
   530
  /// concept. In addition, the \e FullGraph class does not contain a
deba@365
   531
  /// loop arc from each node as the \e FullDigraph does.
deba@365
   532
  ///
deba@365
   533
  /// It also has an important extra feature that its maps are real
deba@365
   534
  /// \ref concepts::ReferenceMap "reference map"s.
deba@365
   535
  ///
deba@365
   536
  /// \sa FullDigraph
deba@365
   537
  class FullGraph : public ExtendedFullGraphBase {
deba@365
   538
  public:
deba@365
   539
deba@365
   540
    typedef ExtendedFullGraphBase Parent;
deba@365
   541
deba@365
   542
    /// \brief Constructor
deba@365
   543
    FullGraph() { construct(0); }
deba@365
   544
deba@365
   545
    /// \brief Constructor
deba@365
   546
    ///
deba@365
   547
    /// \param n The number of the nodes.
deba@365
   548
    FullGraph(int n) { construct(n); }
deba@365
   549
deba@365
   550
    /// \brief Resize the graph
deba@365
   551
    ///
deba@365
   552
    /// Resize the graph. The function will fully destroy and rebuild
deba@365
   553
    /// the graph.  This cause that the maps of the graph will
deba@365
   554
    /// reallocated automatically and the previous values will be
deba@365
   555
    /// lost.
deba@365
   556
    void resize(int n) {
deba@365
   557
      Parent::notifier(Arc()).clear();
deba@365
   558
      Parent::notifier(Edge()).clear();
deba@365
   559
      Parent::notifier(Node()).clear();
deba@365
   560
      construct(n);
deba@365
   561
      Parent::notifier(Node()).build();
deba@365
   562
      Parent::notifier(Edge()).build();
deba@365
   563
      Parent::notifier(Arc()).build();
deba@365
   564
    }
deba@365
   565
deba@365
   566
    /// \brief Returns the node with the given index.
deba@365
   567
    ///
deba@365
   568
    /// Returns the node with the given index. Because it is a static
deba@365
   569
    /// size graph the node's of the graph can be indexed in the range
deba@365
   570
    /// <tt>[0..nodeNum()-1]</tt> and the index of the node can
deba@365
   571
    /// accessed by the \e index() member.
deba@365
   572
    Node operator()(int ix) const { return Parent::operator()(ix); }
deba@365
   573
deba@365
   574
    /// \brief Returns the index of the node.
deba@365
   575
    ///
deba@365
   576
    /// Returns the index of the node. Because it is a static size
deba@365
   577
    /// graph the node's of the graph can be indexed in the range
deba@365
   578
    /// <tt>[0..nodeNum()-1]</tt> and the index of the node can
deba@365
   579
    /// accessed by the \e index() member.
deba@365
   580
    int index(const Node& node) const { return Parent::index(node); }
deba@365
   581
deba@365
   582
    /// \brief Number of nodes.
deba@365
   583
    int nodeNum() const { return Parent::nodeNum(); }
deba@365
   584
    /// \brief Number of arcs.
deba@365
   585
    int arcNum() const { return Parent::arcNum(); }
deba@365
   586
    /// \brief Number of edges.
deba@365
   587
    int edgeNum() const { return Parent::edgeNum(); }
deba@365
   588
deba@365
   589
    /// \brief Returns the arc connects the given nodes.
deba@365
   590
    ///
deba@365
   591
    /// Returns the arc connects the given nodes.
deba@365
   592
    Arc arc(const Node& s, const Node& t) const {
deba@365
   593
      return Parent::arc(s, t);
deba@365
   594
    }
deba@365
   595
deba@365
   596
    /// \brief Returns the edge connects the given nodes.
deba@365
   597
    ///
deba@365
   598
    /// Returns the edge connects the given nodes.
deba@365
   599
    Edge edge(const Node& u, const Node& v) const {
deba@365
   600
      return Parent::edge(u, v);
deba@365
   601
    }
deba@365
   602
  };
deba@365
   603
deba@365
   604
deba@365
   605
} //namespace lemon
deba@365
   606
deba@365
   607
deba@365
   608
#endif //LEMON_FULL_GRAPH_H