lemon/graph_adaptor.h
author alpar
Mon, 06 Feb 2006 09:11:53 +0000
changeset 1960 a60b681d0825
parent 1956 a055123339d5
child 1979 c2992fd74dad
permissions -rw-r--r--
- Increased max. number of iteration
- Better tests.
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@1359
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@906
     8
 *
alpar@906
     9
 * Permission to use, modify and distribute this software is granted
alpar@906
    10
 * provided that this copyright notice appears in all copies. For
alpar@906
    11
 * precise terms see the accompanying LICENSE file.
alpar@906
    12
 *
alpar@906
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    14
 * express or implied, and with no claim as to its suitability for any
alpar@906
    15
 * purpose.
alpar@906
    16
 *
alpar@906
    17
 */
alpar@906
    18
alpar@1401
    19
#ifndef LEMON_GRAPH_ADAPTOR_H
alpar@1401
    20
#define LEMON_GRAPH_ADAPTOR_H
marci@556
    21
alpar@1401
    22
///\ingroup graph_adaptors
marci@556
    23
///\file
alpar@1401
    24
///\brief Several graph adaptors.
marci@556
    25
///
alpar@1401
    26
///This file contains several useful graph adaptor functions.
marci@556
    27
///
marci@556
    28
///\author Marton Makai
marci@556
    29
alpar@921
    30
#include <lemon/invalid.h>
alpar@921
    31
#include <lemon/maps.h>
deba@1472
    32
#include <lemon/bits/erasable_graph_extender.h>
deba@1472
    33
#include <lemon/bits/clearable_graph_extender.h>
deba@1472
    34
#include <lemon/bits/extendable_graph_extender.h>
deba@1307
    35
#include <lemon/bits/iterable_graph_extender.h>
deba@1472
    36
#include <lemon/bits/alteration_notifier.h>
deba@1472
    37
#include <lemon/bits/default_map.h>
deba@1791
    38
#include <lemon/bits/graph_extender.h>
alpar@774
    39
#include <iostream>
marci@556
    40
alpar@921
    41
namespace lemon {
marci@556
    42
klao@1951
    43
  ///\brief Base type for the Graph Adaptors
klao@1951
    44
  ///\ingroup graph_adaptors
klao@1951
    45
  ///
klao@1951
    46
  ///Base type for the Graph Adaptors
klao@1951
    47
  ///
klao@1951
    48
  ///\warning Graph adaptors are in even
klao@1951
    49
  ///more experimental state than the other
klao@1951
    50
  ///parts of the lib. Use them at you own risk.
klao@1951
    51
  ///
klao@1951
    52
  ///This is the base type for most of LEMON graph adaptors. 
klao@1951
    53
  ///This class implements a trivial graph adaptor i.e. it only wraps the 
klao@1951
    54
  ///functions and types of the graph. The purpose of this class is to 
klao@1951
    55
  ///make easier implementing graph adaptors. E.g. if an adaptor is 
klao@1951
    56
  ///considered which differs from the wrapped graph only in some of its 
klao@1951
    57
  ///functions or types, then it can be derived from GraphAdaptor,
klao@1951
    58
  ///and only the 
klao@1951
    59
  ///differences should be implemented.
klao@1951
    60
  ///
klao@1951
    61
  ///author Marton Makai 
marci@970
    62
  template<typename _Graph>
alpar@1401
    63
  class GraphAdaptorBase {
marci@970
    64
  public:
marci@970
    65
    typedef _Graph Graph;
marci@970
    66
    typedef Graph ParentGraph;
marci@970
    67
marci@556
    68
  protected:
marci@556
    69
    Graph* graph;
alpar@1401
    70
    GraphAdaptorBase() : graph(0) { }
marci@556
    71
    void setGraph(Graph& _graph) { graph=&_graph; }
marci@556
    72
marci@556
    73
  public:
alpar@1401
    74
    GraphAdaptorBase(Graph& _graph) : graph(&_graph) { }
marci@556
    75
 
alpar@774
    76
    typedef typename Graph::Node Node;
alpar@774
    77
    typedef typename Graph::Edge Edge;
marci@556
    78
   
marci@970
    79
    void first(Node& i) const { graph->first(i); }
marci@970
    80
    void first(Edge& i) const { graph->first(i); }
marci@970
    81
    void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
marci@970
    82
    void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
marci@556
    83
marci@970
    84
    void next(Node& i) const { graph->next(i); }
marci@970
    85
    void next(Edge& i) const { graph->next(i); }
marci@970
    86
    void nextIn(Edge& i) const { graph->nextIn(i); }
marci@970
    87
    void nextOut(Edge& i) const { graph->nextOut(i); }
marci@970
    88
alpar@986
    89
    Node source(const Edge& e) const { return graph->source(e); }
alpar@986
    90
    Node target(const Edge& e) const { return graph->target(e); }
marci@556
    91
deba@1697
    92
    typedef NodeNumTagIndicator<Graph> NodeNumTag;
marci@556
    93
    int nodeNum() const { return graph->nodeNum(); }
deba@1697
    94
    
deba@1697
    95
    typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
marci@556
    96
    int edgeNum() const { return graph->edgeNum(); }
deba@1697
    97
deba@1697
    98
    typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
deba@1697
    99
    Edge findEdge(const Node& source, const Node& target, 
deba@1697
   100
		  const Edge& prev = INVALID) {
deba@1697
   101
      return graph->findEdge(source, target, prev);
deba@1697
   102
    }
marci@556
   103
  
deba@1697
   104
    Node addNode() const { 
deba@1697
   105
      return Node(graph->addNode()); 
deba@1697
   106
    }
deba@1697
   107
alpar@986
   108
    Edge addEdge(const Node& source, const Node& target) const { 
deba@1697
   109
      return Edge(graph->addEdge(source, target)); 
deba@1697
   110
    }
marci@556
   111
marci@556
   112
    void erase(const Node& i) const { graph->erase(i); }
marci@556
   113
    void erase(const Edge& i) const { graph->erase(i); }
marci@556
   114
  
marci@556
   115
    void clear() const { graph->clear(); }
marci@556
   116
    
marci@739
   117
    int id(const Node& v) const { return graph->id(v); }
marci@739
   118
    int id(const Edge& e) const { return graph->id(e); }
marci@650
   119
    
deba@1627
   120
    Edge oppositeNode(const Edge& e) const { 
deba@1627
   121
      return Edge(graph->opposite(e)); 
deba@1627
   122
    }
marci@650
   123
marci@970
   124
    template <typename _Value>
marci@970
   125
    class NodeMap : public _Graph::template NodeMap<_Value> {
marci@970
   126
    public:
marci@970
   127
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@1755
   128
      explicit NodeMap(const GraphAdaptorBase<_Graph>& gw) 
deba@1755
   129
	: Parent(*gw.graph) { }
alpar@1401
   130
      NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
deba@1755
   131
	: Parent(*gw.graph, value) { }
marci@970
   132
    };
marci@556
   133
marci@970
   134
    template <typename _Value>
marci@970
   135
    class EdgeMap : public _Graph::template EdgeMap<_Value> {
marci@970
   136
    public:
marci@970
   137
      typedef typename _Graph::template EdgeMap<_Value> Parent;
deba@1755
   138
      explicit EdgeMap(const GraphAdaptorBase<_Graph>& gw) 
deba@1755
   139
	: Parent(*gw.graph) { }
alpar@1401
   140
      EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
deba@1755
   141
	: Parent(*gw.graph, value) { }
marci@970
   142
    };
deba@877
   143
marci@556
   144
  };
marci@556
   145
marci@970
   146
  template <typename _Graph>
alpar@1401
   147
  class GraphAdaptor :
alpar@1401
   148
    public IterableGraphExtender<GraphAdaptorBase<_Graph> > { 
marci@970
   149
  public:
marci@970
   150
    typedef _Graph Graph;
alpar@1401
   151
    typedef IterableGraphExtender<GraphAdaptorBase<_Graph> > Parent;
marci@970
   152
  protected:
alpar@1401
   153
    GraphAdaptor() : Parent() { }
marci@569
   154
marci@970
   155
  public:
deba@1755
   156
    explicit GraphAdaptor(Graph& _graph) { setGraph(_graph); }
marci@970
   157
  };
marci@569
   158
marci@997
   159
  template <typename _Graph>
alpar@1401
   160
  class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
marci@997
   161
  public:
marci@997
   162
    typedef _Graph Graph;
alpar@1401
   163
    typedef GraphAdaptorBase<_Graph> Parent;
marci@997
   164
  protected:
alpar@1401
   165
    RevGraphAdaptorBase() : Parent() { }
marci@997
   166
  public:
marci@997
   167
    typedef typename Parent::Node Node;
marci@997
   168
    typedef typename Parent::Edge Edge;
marci@997
   169
marci@997
   170
    void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
marci@997
   171
    void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
marci@997
   172
marci@997
   173
    void nextIn(Edge& i) const { Parent::nextOut(i); }
marci@997
   174
    void nextOut(Edge& i) const { Parent::nextIn(i); }
marci@997
   175
marci@997
   176
    Node source(const Edge& e) const { return Parent::target(e); }
marci@997
   177
    Node target(const Edge& e) const { return Parent::source(e); }
marci@997
   178
  };
marci@997
   179
    
marci@997
   180
alpar@1949
   181
  ///\brief A graph adaptor which reverses the orientation of the edges.
alpar@1949
   182
  ///\ingroup graph_adaptors
alpar@1949
   183
  ///
alpar@1949
   184
  ///\warning Graph adaptors are in even more experimental 
alpar@1949
   185
  ///state than the other
alpar@879
   186
  ///parts of the lib. Use them at you own risk.
alpar@879
   187
  ///
alpar@1949
   188
  /// If \c g is defined as
alpar@1946
   189
  ///\code
marci@923
   190
  /// ListGraph g;
alpar@1946
   191
  ///\endcode
alpar@1949
   192
  /// then
alpar@1946
   193
  ///\code
alpar@1401
   194
  /// RevGraphAdaptor<ListGraph> gw(g);
alpar@1946
   195
  ///\endcode
alpar@1949
   196
  ///implements the graph obtained from \c g by 
alpar@1949
   197
  /// reversing the orientation of its edges.
alpar@1946
   198
marci@997
   199
  template<typename _Graph>
alpar@1401
   200
  class RevGraphAdaptor : 
alpar@1401
   201
    public IterableGraphExtender<RevGraphAdaptorBase<_Graph> > {
marci@650
   202
  public:
marci@997
   203
    typedef _Graph Graph;
marci@997
   204
    typedef IterableGraphExtender<
alpar@1401
   205
      RevGraphAdaptorBase<_Graph> > Parent;
marci@556
   206
  protected:
alpar@1401
   207
    RevGraphAdaptor() { }
marci@556
   208
  public:
deba@1755
   209
    explicit RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
marci@997
   210
  };
marci@556
   211
marci@992
   212
  
deba@1681
   213
  template <typename _Graph, typename NodeFilterMap, 
deba@1681
   214
	    typename EdgeFilterMap, bool checked = true>
alpar@1401
   215
  class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
marci@992
   216
  public:
marci@992
   217
    typedef _Graph Graph;
alpar@1401
   218
    typedef GraphAdaptorBase<_Graph> Parent;
marci@992
   219
  protected:
marci@992
   220
    NodeFilterMap* node_filter_map;
marci@992
   221
    EdgeFilterMap* edge_filter_map;
alpar@1401
   222
    SubGraphAdaptorBase() : Parent(), 
marci@992
   223
			    node_filter_map(0), edge_filter_map(0) { }
marci@775
   224
marci@992
   225
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
marci@992
   226
      node_filter_map=&_node_filter_map;
marci@992
   227
    }
marci@992
   228
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
marci@992
   229
      edge_filter_map=&_edge_filter_map;
marci@992
   230
    }
marci@992
   231
marci@992
   232
  public:
marci@992
   233
marci@992
   234
    typedef typename Parent::Node Node;
marci@992
   235
    typedef typename Parent::Edge Edge;
marci@992
   236
marci@992
   237
    void first(Node& i) const { 
marci@992
   238
      Parent::first(i); 
marci@992
   239
      while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i); 
marci@992
   240
    }
deba@1681
   241
deba@1681
   242
    void first(Edge& i) const { 
deba@1681
   243
      Parent::first(i); 
deba@1681
   244
      while (i!=INVALID && (!(*edge_filter_map)[i] 
deba@1681
   245
	     || !(*node_filter_map)[Parent::source(i)]
deba@1681
   246
	     || !(*node_filter_map)[Parent::target(i)])) Parent::next(i); 
deba@1681
   247
    }
deba@1681
   248
deba@1681
   249
    void firstIn(Edge& i, const Node& n) const { 
deba@1681
   250
      Parent::firstIn(i, n); 
deba@1681
   251
      while (i!=INVALID && (!(*edge_filter_map)[i] 
deba@1681
   252
	     || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i); 
deba@1681
   253
    }
deba@1681
   254
deba@1681
   255
    void firstOut(Edge& i, const Node& n) const { 
deba@1681
   256
      Parent::firstOut(i, n); 
deba@1681
   257
      while (i!=INVALID && (!(*edge_filter_map)[i] 
deba@1681
   258
	     || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i); 
deba@1681
   259
    }
deba@1681
   260
deba@1681
   261
    void next(Node& i) const { 
deba@1681
   262
      Parent::next(i); 
deba@1681
   263
      while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i); 
deba@1681
   264
    }
deba@1681
   265
deba@1681
   266
    void next(Edge& i) const { 
deba@1681
   267
      Parent::next(i); 
deba@1681
   268
      while (i!=INVALID && (!(*edge_filter_map)[i] 
deba@1681
   269
	     || !(*node_filter_map)[Parent::source(i)]
deba@1681
   270
	     || !(*node_filter_map)[Parent::target(i)])) Parent::next(i); 
deba@1681
   271
    }
deba@1681
   272
deba@1681
   273
    void nextIn(Edge& i) const { 
deba@1681
   274
      Parent::nextIn(i); 
deba@1681
   275
      while (i!=INVALID && (!(*edge_filter_map)[i] 
deba@1681
   276
	     || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i); 
deba@1681
   277
    }
deba@1681
   278
deba@1681
   279
    void nextOut(Edge& i) const { 
deba@1681
   280
      Parent::nextOut(i); 
deba@1681
   281
      while (i!=INVALID && (!(*edge_filter_map)[i] 
deba@1681
   282
	     || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i); 
deba@1681
   283
    }
deba@1681
   284
klao@1951
   285
    ///\e
alpar@1949
   286
klao@1951
   287
    /// This function hides \c n in the graph, i.e. the iteration 
klao@1951
   288
    /// jumps over it. This is done by simply setting the value of \c n  
klao@1951
   289
    /// to be false in the corresponding node-map.
deba@1681
   290
    void hide(const Node& n) const { node_filter_map->set(n, false); }
deba@1681
   291
klao@1951
   292
    ///\e
alpar@1949
   293
klao@1951
   294
    /// This function hides \c e in the graph, i.e. the iteration 
klao@1951
   295
    /// jumps over it. This is done by simply setting the value of \c e  
klao@1951
   296
    /// to be false in the corresponding edge-map.
deba@1681
   297
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
deba@1681
   298
klao@1951
   299
    ///\e
alpar@1949
   300
klao@1951
   301
    /// The value of \c n is set to be true in the node-map which stores 
klao@1951
   302
    /// hide information. If \c n was hidden previuosly, then it is shown 
klao@1951
   303
    /// again
deba@1681
   304
     void unHide(const Node& n) const { node_filter_map->set(n, true); }
deba@1681
   305
klao@1951
   306
    ///\e
alpar@1949
   307
klao@1951
   308
    /// The value of \c e is set to be true in the edge-map which stores 
klao@1951
   309
    /// hide information. If \c e was hidden previuosly, then it is shown 
klao@1951
   310
    /// again
deba@1681
   311
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
deba@1681
   312
klao@1951
   313
    /// Returns true if \c n is hidden.
alpar@1949
   314
    
klao@1951
   315
    ///\e
klao@1951
   316
    ///
deba@1681
   317
    bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
deba@1681
   318
klao@1951
   319
    /// Returns true if \c n is hidden.
alpar@1949
   320
    
klao@1951
   321
    ///\e
klao@1951
   322
    ///
deba@1681
   323
    bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
deba@1681
   324
deba@1697
   325
    typedef False NodeNumTag;
deba@1697
   326
    typedef False EdgeNumTag;
deba@1681
   327
  };
deba@1681
   328
deba@1681
   329
  template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
deba@1681
   330
  class SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, false> 
deba@1681
   331
    : public GraphAdaptorBase<_Graph> {
deba@1681
   332
  public:
deba@1681
   333
    typedef _Graph Graph;
deba@1681
   334
    typedef GraphAdaptorBase<_Graph> Parent;
deba@1681
   335
  protected:
deba@1681
   336
    NodeFilterMap* node_filter_map;
deba@1681
   337
    EdgeFilterMap* edge_filter_map;
deba@1681
   338
    SubGraphAdaptorBase() : Parent(), 
deba@1681
   339
			    node_filter_map(0), edge_filter_map(0) { }
deba@1681
   340
deba@1681
   341
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
deba@1681
   342
      node_filter_map=&_node_filter_map;
deba@1681
   343
    }
deba@1681
   344
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
deba@1681
   345
      edge_filter_map=&_edge_filter_map;
deba@1681
   346
    }
deba@1681
   347
deba@1681
   348
  public:
deba@1681
   349
deba@1681
   350
    typedef typename Parent::Node Node;
deba@1681
   351
    typedef typename Parent::Edge Edge;
deba@1681
   352
deba@1681
   353
    void first(Node& i) const { 
deba@1681
   354
      Parent::first(i); 
deba@1681
   355
      while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i); 
deba@1681
   356
    }
deba@1681
   357
marci@992
   358
    void first(Edge& i) const { 
marci@992
   359
      Parent::first(i); 
marci@992
   360
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i); 
marci@992
   361
    }
deba@1681
   362
marci@992
   363
    void firstIn(Edge& i, const Node& n) const { 
marci@992
   364
      Parent::firstIn(i, n); 
marci@992
   365
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i); 
marci@992
   366
    }
deba@1681
   367
marci@992
   368
    void firstOut(Edge& i, const Node& n) const { 
marci@992
   369
      Parent::firstOut(i, n); 
marci@992
   370
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i); 
marci@992
   371
    }
marci@992
   372
marci@992
   373
    void next(Node& i) const { 
marci@992
   374
      Parent::next(i); 
marci@992
   375
      while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i); 
marci@992
   376
    }
marci@992
   377
    void next(Edge& i) const { 
marci@992
   378
      Parent::next(i); 
marci@992
   379
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i); 
marci@992
   380
    }
marci@992
   381
    void nextIn(Edge& i) const { 
marci@992
   382
      Parent::nextIn(i); 
marci@992
   383
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i); 
marci@992
   384
    }
deba@1681
   385
marci@992
   386
    void nextOut(Edge& i) const { 
marci@992
   387
      Parent::nextOut(i); 
marci@992
   388
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i); 
marci@992
   389
    }
marci@992
   390
klao@1951
   391
    ///\e
alpar@1949
   392
klao@1951
   393
    /// This function hides \c n in the graph, i.e. the iteration 
klao@1951
   394
    /// jumps over it. This is done by simply setting the value of \c n  
klao@1951
   395
    /// to be false in the corresponding node-map.
marci@992
   396
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@992
   397
klao@1951
   398
    ///\e
alpar@1949
   399
klao@1951
   400
    /// This function hides \c e in the graph, i.e. the iteration 
klao@1951
   401
    /// jumps over it. This is done by simply setting the value of \c e  
klao@1951
   402
    /// to be false in the corresponding edge-map.
marci@992
   403
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@992
   404
klao@1951
   405
    ///\e
alpar@1949
   406
klao@1951
   407
    /// The value of \c n is set to be true in the node-map which stores 
klao@1951
   408
    /// hide information. If \c n was hidden previuosly, then it is shown 
klao@1951
   409
    /// again
marci@992
   410
     void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@992
   411
klao@1951
   412
    ///\e
alpar@1949
   413
klao@1951
   414
    /// The value of \c e is set to be true in the edge-map which stores 
klao@1951
   415
    /// hide information. If \c e was hidden previuosly, then it is shown 
klao@1951
   416
    /// again
marci@992
   417
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@992
   418
klao@1951
   419
    /// Returns true if \c n is hidden.
alpar@1949
   420
    
klao@1951
   421
    ///\e
klao@1951
   422
    ///
marci@992
   423
    bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
marci@992
   424
klao@1951
   425
    /// Returns true if \c n is hidden.
alpar@1949
   426
    
klao@1951
   427
    ///\e
klao@1951
   428
    ///
marci@992
   429
    bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
marci@992
   430
deba@1697
   431
    typedef False NodeNumTag;
deba@1697
   432
    typedef False EdgeNumTag;
marci@992
   433
  };
marci@775
   434
klao@1951
   435
  /// \brief A graph adaptor for hiding nodes and edges from a graph.
klao@1951
   436
  /// \ingroup graph_adaptors
klao@1951
   437
  /// 
klao@1951
   438
  /// \warning Graph adaptors are in even more experimental state than the
klao@1951
   439
  /// other parts of the lib. Use them at you own risk.
klao@1951
   440
  /// 
klao@1951
   441
  /// SubGraphAdaptor shows the graph with filtered node-set and 
klao@1951
   442
  /// edge-set. If the \c checked parameter is true then it filters the edgeset
klao@1951
   443
  /// to do not get invalid edges without source or target.
klao@1952
   444
  /// Let \f$ G=(V, A) \f$ be a directed graph
klao@1951
   445
  /// and suppose that the graph instance \c g of type ListGraph
klao@1952
   446
  /// implements \f$ G \f$.
klao@1952
   447
  /// Let moreover \f$ b_V \f$ and \f$ b_A \f$ be bool-valued functions resp.
klao@1951
   448
  /// on the node-set and edge-set.
klao@1951
   449
  /// SubGraphAdaptor<...>::NodeIt iterates 
klao@1952
   450
  /// on the node-set \f$ \{v\in V : b_V(v)=true\} \f$ and 
klao@1951
   451
  /// SubGraphAdaptor<...>::EdgeIt iterates 
klao@1952
   452
  /// on the edge-set \f$ \{e\in A : b_A(e)=true\} \f$. Similarly, 
klao@1951
   453
  /// SubGraphAdaptor<...>::OutEdgeIt and
klao@1951
   454
  /// SubGraphAdaptor<...>::InEdgeIt iterates 
klao@1951
   455
  /// only on edges leaving and entering a specific node which have true value.
klao@1951
   456
  /// 
klao@1951
   457
  /// If the \c checked template parameter is false then we have to note that 
klao@1951
   458
  /// the node-iterator cares only the filter on the node-set, and the 
klao@1951
   459
  /// edge-iterator cares only the filter on the edge-set.
klao@1951
   460
  /// This way the edge-map
klao@1951
   461
  /// should filter all edges which's source or target is filtered by the 
klao@1951
   462
  /// node-filter.
alpar@1957
   463
  ///\code
klao@1951
   464
  /// typedef ListGraph Graph;
klao@1951
   465
  /// Graph g;
klao@1951
   466
  /// typedef Graph::Node Node;
klao@1951
   467
  /// typedef Graph::Edge Edge;
klao@1951
   468
  /// Node u=g.addNode(); //node of id 0
klao@1951
   469
  /// Node v=g.addNode(); //node of id 1
klao@1951
   470
  /// Node e=g.addEdge(u, v); //edge of id 0
klao@1951
   471
  /// Node f=g.addEdge(v, u); //edge of id 1
klao@1951
   472
  /// Graph::NodeMap<bool> nm(g, true);
klao@1951
   473
  /// nm.set(u, false);
klao@1951
   474
  /// Graph::EdgeMap<bool> em(g, true);
klao@1951
   475
  /// em.set(e, false);
klao@1951
   476
  /// typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
klao@1951
   477
  /// SubGW gw(g, nm, em);
klao@1951
   478
  /// for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
klao@1951
   479
  /// std::cout << ":-)" << std::endl;
klao@1951
   480
  /// for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
alpar@1957
   481
  ///\endcode
klao@1951
   482
  /// The output of the above code is the following.
alpar@1957
   483
  ///\code
klao@1951
   484
  /// 1
klao@1951
   485
  /// :-)
klao@1951
   486
  /// 1
alpar@1957
   487
  ///\endcode
klao@1951
   488
  /// Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
klao@1951
   489
  /// \c Graph::Node that is why \c g.id(n) can be applied.
klao@1951
   490
  /// 
klao@1951
   491
  /// For other examples see also the documentation of NodeSubGraphAdaptor and 
klao@1951
   492
  /// EdgeSubGraphAdaptor.
klao@1951
   493
  /// 
klao@1951
   494
  /// \author Marton Makai
marci@1242
   495
marci@992
   496
  template<typename _Graph, typename NodeFilterMap, 
deba@1681
   497
	   typename EdgeFilterMap, bool checked = true>
alpar@1401
   498
  class SubGraphAdaptor : 
marci@992
   499
    public IterableGraphExtender<
deba@1681
   500
    SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > {
marci@650
   501
  public:
marci@992
   502
    typedef _Graph Graph;
marci@992
   503
    typedef IterableGraphExtender<
alpar@1401
   504
      SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
marci@556
   505
  protected:
alpar@1401
   506
    SubGraphAdaptor() { }
marci@992
   507
  public:
alpar@1401
   508
    SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@992
   509
		    EdgeFilterMap& _edge_filter_map) { 
marci@992
   510
      setGraph(_graph);
marci@992
   511
      setNodeFilterMap(_node_filter_map);
marci@992
   512
      setEdgeFilterMap(_edge_filter_map);
marci@992
   513
    }
marci@992
   514
  };
marci@556
   515
marci@556
   516
marci@569
   517
klao@1951
   518
  ///\brief An adaptor for hiding nodes from a graph.
klao@1951
   519
  ///\ingroup graph_adaptors
klao@1951
   520
  ///
klao@1951
   521
  ///\warning Graph adaptors are in even more experimental state
klao@1951
   522
  ///than the other
klao@1951
   523
  ///parts of the lib. Use them at you own risk.
klao@1951
   524
  ///
klao@1951
   525
  ///An adaptor for hiding nodes from a graph.
klao@1951
   526
  ///This adaptor specializes SubGraphAdaptor in the way that only
klao@1951
   527
  ///the node-set 
klao@1951
   528
  ///can be filtered. In usual case the checked parameter is true, we get the
klao@1951
   529
  ///induced subgraph. But if the checked parameter is false then we can only
klao@1951
   530
  ///filter only isolated nodes.
klao@1951
   531
  ///\author Marton Makai
deba@1681
   532
  template<typename Graph, typename NodeFilterMap, bool checked = true>
alpar@1401
   533
  class NodeSubGraphAdaptor : 
alpar@1401
   534
    public SubGraphAdaptor<Graph, NodeFilterMap, 
deba@1681
   535
			   ConstMap<typename Graph::Edge,bool>, checked> {
marci@933
   536
  public:
alpar@1401
   537
    typedef SubGraphAdaptor<Graph, NodeFilterMap, 
marci@933
   538
			    ConstMap<typename Graph::Edge,bool> > Parent;
marci@933
   539
  protected:
marci@933
   540
    ConstMap<typename Graph::Edge, bool> const_true_map;
marci@933
   541
  public:
alpar@1401
   542
    NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) : 
marci@933
   543
      Parent(), const_true_map(true) { 
marci@933
   544
      Parent::setGraph(_graph);
marci@933
   545
      Parent::setNodeFilterMap(_node_filter_map);
marci@933
   546
      Parent::setEdgeFilterMap(const_true_map);
marci@933
   547
    }
marci@933
   548
  };
marci@933
   549
marci@933
   550
klao@1951
   551
  ///\brief An adaptor for hiding edges from a graph.
klao@1951
   552
  ///
klao@1951
   553
  ///\warning Graph adaptors are in even more experimental state
klao@1951
   554
  ///than the other parts of the lib. Use them at you own risk.
klao@1951
   555
  ///
klao@1951
   556
  ///An adaptor for hiding edges from a graph.
klao@1951
   557
  ///This adaptor specializes SubGraphAdaptor in the way that
klao@1951
   558
  ///only the edge-set 
klao@1951
   559
  ///can be filtered. The usefulness of this adaptor is demonstrated in the 
klao@1951
   560
  ///problem of searching a maximum number of edge-disjoint shortest paths 
klao@1951
   561
  ///between 
klao@1951
   562
  ///two nodes \c s and \c t. Shortest here means being shortest w.r.t. 
klao@1951
   563
  ///non-negative edge-lengths. Note that 
klao@1951
   564
  ///the comprehension of the presented solution 
klao@1951
   565
  ///need's some elementary knowledge from combinatorial optimization. 
klao@1951
   566
  ///
klao@1951
   567
  ///If a single shortest path is to be 
klao@1951
   568
  ///searched between \c s and \c t, then this can be done easily by 
klao@1951
   569
  ///applying the Dijkstra algorithm. What happens, if a maximum number of 
klao@1951
   570
  ///edge-disjoint shortest paths is to be computed. It can be proved that an 
klao@1951
   571
  ///edge can be in a shortest path if and only
klao@1951
   572
  ///if it is tight with respect to 
klao@1951
   573
  ///the potential function computed by Dijkstra.
klao@1951
   574
  ///Moreover, any path containing 
klao@1951
   575
  ///only such edges is a shortest one.
klao@1951
   576
  ///Thus we have to compute a maximum number 
klao@1951
   577
  ///of edge-disjoint paths between \c s and \c t in
klao@1951
   578
  ///the graph which has edge-set 
klao@1951
   579
  ///all the tight edges. The computation will be demonstrated
klao@1951
   580
  ///on the following 
klao@1951
   581
  ///graph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim. 
klao@1951
   582
  ///The full source code is available in \ref sub_graph_adaptor_demo.cc. 
klao@1951
   583
  ///If you are interested in more demo programs, you can use 
klao@1951
   584
  ///\ref dim_to_dot.cc to generate .dot files from dimacs files. 
klao@1951
   585
  ///The .dot file of the following figure was generated by  
klao@1951
   586
  ///the demo program \ref dim_to_dot.cc.
klao@1951
   587
  ///
klao@1951
   588
  ///\dot
klao@1951
   589
  ///digraph lemon_dot_example {
klao@1951
   590
  ///node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
klao@1951
   591
  ///n0 [ label="0 (s)" ];
klao@1951
   592
  ///n1 [ label="1" ];
klao@1951
   593
  ///n2 [ label="2" ];
klao@1951
   594
  ///n3 [ label="3" ];
klao@1951
   595
  ///n4 [ label="4" ];
klao@1951
   596
  ///n5 [ label="5" ];
klao@1951
   597
  ///n6 [ label="6 (t)" ];
klao@1951
   598
  ///edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
klao@1951
   599
  ///n5 ->  n6 [ label="9, length:4" ];
klao@1951
   600
  ///n4 ->  n6 [ label="8, length:2" ];
klao@1951
   601
  ///n3 ->  n5 [ label="7, length:1" ];
klao@1951
   602
  ///n2 ->  n5 [ label="6, length:3" ];
klao@1951
   603
  ///n2 ->  n6 [ label="5, length:5" ];
klao@1951
   604
  ///n2 ->  n4 [ label="4, length:2" ];
klao@1951
   605
  ///n1 ->  n4 [ label="3, length:3" ];
klao@1951
   606
  ///n0 ->  n3 [ label="2, length:1" ];
klao@1951
   607
  ///n0 ->  n2 [ label="1, length:2" ];
klao@1951
   608
  ///n0 ->  n1 [ label="0, length:3" ];
klao@1951
   609
  ///}
klao@1951
   610
  ///\enddot
klao@1951
   611
  ///
klao@1951
   612
  ///\code
klao@1951
   613
  ///Graph g;
klao@1951
   614
  ///Node s, t;
klao@1951
   615
  ///LengthMap length(g);
klao@1951
   616
  ///
klao@1951
   617
  ///readDimacs(std::cin, g, length, s, t);
klao@1951
   618
  ///
klao@1951
   619
  ///cout << "edges with lengths (of form id, source--length->target): " << endl;
klao@1951
   620
  ///for(EdgeIt e(g); e!=INVALID; ++e) 
klao@1951
   621
  ///  cout << g.id(e) << ", " << g.id(g.source(e)) << "--" 
klao@1951
   622
  ///       << length[e] << "->" << g.id(g.target(e)) << endl;
klao@1951
   623
  ///
klao@1951
   624
  ///cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
klao@1951
   625
  ///\endcode
klao@1951
   626
  ///Next, the potential function is computed with Dijkstra.
klao@1951
   627
  ///\code
klao@1951
   628
  ///typedef Dijkstra<Graph, LengthMap> Dijkstra;
klao@1951
   629
  ///Dijkstra dijkstra(g, length);
klao@1951
   630
  ///dijkstra.run(s);
klao@1951
   631
  ///\endcode
klao@1951
   632
  ///Next, we consrtruct a map which filters the edge-set to the tight edges.
klao@1951
   633
  ///\code
klao@1951
   634
  ///typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap> 
klao@1951
   635
  ///  TightEdgeFilter;
klao@1951
   636
  ///TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
klao@1951
   637
  ///
klao@1951
   638
  ///typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
klao@1951
   639
  ///SubGW gw(g, tight_edge_filter);
klao@1951
   640
  ///\endcode
klao@1951
   641
  ///Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed 
klao@1951
   642
  ///with a max flow algorithm Preflow.
klao@1951
   643
  ///\code
klao@1951
   644
  ///ConstMap<Edge, int> const_1_map(1);
klao@1951
   645
  ///Graph::EdgeMap<int> flow(g, 0);
klao@1951
   646
  ///
klao@1951
   647
  ///Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > 
klao@1951
   648
  ///  preflow(gw, s, t, const_1_map, flow);
klao@1951
   649
  ///preflow.run();
klao@1951
   650
  ///\endcode
klao@1951
   651
  ///Last, the output is:
klao@1951
   652
  ///\code  
klao@1951
   653
  ///cout << "maximum number of edge-disjoint shortest path: " 
klao@1951
   654
  ///     << preflow.flowValue() << endl;
klao@1951
   655
  ///cout << "edges of the maximum number of edge-disjoint shortest s-t paths: " 
klao@1951
   656
  ///     << endl;
klao@1951
   657
  ///for(EdgeIt e(g); e!=INVALID; ++e) 
klao@1951
   658
  ///  if (flow[e])
klao@1951
   659
  ///    cout << " " << g.id(g.source(e)) << "--"
klao@1951
   660
  ///         << length[e] << "->" << g.id(g.target(e)) << endl;
klao@1951
   661
  ///\endcode
klao@1951
   662
  ///The program has the following (expected :-)) output:
klao@1951
   663
  ///\code
klao@1951
   664
  ///edges with lengths (of form id, source--length->target):
klao@1951
   665
  /// 9, 5--4->6
klao@1951
   666
  /// 8, 4--2->6
klao@1951
   667
  /// 7, 3--1->5
klao@1951
   668
  /// 6, 2--3->5
klao@1951
   669
  /// 5, 2--5->6
klao@1951
   670
  /// 4, 2--2->4
klao@1951
   671
  /// 3, 1--3->4
klao@1951
   672
  /// 2, 0--1->3
klao@1951
   673
  /// 1, 0--2->2
klao@1951
   674
  /// 0, 0--3->1
klao@1951
   675
  ///s: 0 t: 6
klao@1951
   676
  ///maximum number of edge-disjoint shortest path: 2
klao@1951
   677
  ///edges of the maximum number of edge-disjoint shortest s-t paths:
klao@1951
   678
  /// 9, 5--4->6
klao@1951
   679
  /// 8, 4--2->6
klao@1951
   680
  /// 7, 3--1->5
klao@1951
   681
  /// 4, 2--2->4
klao@1951
   682
  /// 2, 0--1->3
klao@1951
   683
  /// 1, 0--2->2
klao@1951
   684
  ///\endcode
klao@1951
   685
  ///
klao@1951
   686
  ///\author Marton Makai
marci@932
   687
  template<typename Graph, typename EdgeFilterMap>
alpar@1401
   688
  class EdgeSubGraphAdaptor : 
alpar@1401
   689
    public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>, 
deba@1681
   690
			   EdgeFilterMap, false> {
marci@932
   691
  public:
alpar@1401
   692
    typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>, 
deba@1685
   693
			    EdgeFilterMap, false> Parent;
marci@932
   694
  protected:
marci@932
   695
    ConstMap<typename Graph::Node, bool> const_true_map;
marci@932
   696
  public:
alpar@1401
   697
    EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) : 
marci@932
   698
      Parent(), const_true_map(true) { 
marci@932
   699
      Parent::setGraph(_graph);
marci@932
   700
      Parent::setNodeFilterMap(const_true_map);
marci@932
   701
      Parent::setEdgeFilterMap(_edge_filter_map);
marci@932
   702
    }
marci@932
   703
  };
marci@932
   704
marci@1383
   705
  template <typename _Graph>
klao@1909
   706
  class UGraphAdaptorBase : 
klao@1909
   707
    public UGraphExtender<GraphAdaptorBase<_Graph> > {
marci@1383
   708
  public:
marci@1383
   709
    typedef _Graph Graph;
klao@1909
   710
    typedef UGraphExtender<GraphAdaptorBase<_Graph> > Parent;
marci@1383
   711
  protected:
klao@1909
   712
    UGraphAdaptorBase() : Parent() { }
marci@1383
   713
  public:
klao@1909
   714
    typedef typename Parent::UEdge UEdge;
marci@1383
   715
    typedef typename Parent::Edge Edge;
marci@1383
   716
    
marci@1383
   717
    template <typename T>
marci@1383
   718
    class EdgeMap {
marci@1383
   719
    protected:
klao@1909
   720
      const UGraphAdaptorBase<_Graph>* g;
marci@1383
   721
      template <typename TT> friend class EdgeMap;
marci@1383
   722
      typename _Graph::template EdgeMap<T> forward_map, backward_map; 
marci@1383
   723
    public:
marci@1383
   724
      typedef T Value;
marci@1383
   725
      typedef Edge Key;
marci@1383
   726
      
klao@1909
   727
      EdgeMap(const UGraphAdaptorBase<_Graph>& _g) : g(&_g), 
marci@1383
   728
	forward_map(*(g->graph)), backward_map(*(g->graph)) { }
marci@569
   729
klao@1909
   730
      EdgeMap(const UGraphAdaptorBase<_Graph>& _g, T a) : g(&_g), 
marci@1383
   731
	forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
marci@1383
   732
      
marci@1383
   733
      void set(Edge e, T a) { 
deba@1627
   734
	if (g->direction(e)) 
marci@1383
   735
	  forward_map.set(e, a); 
marci@1383
   736
	else 
marci@1383
   737
	  backward_map.set(e, a); 
marci@1383
   738
      }
marci@556
   739
marci@1383
   740
      T operator[](Edge e) const { 
deba@1627
   741
	if (g->direction(e)) 
marci@1383
   742
	  return forward_map[e]; 
marci@1383
   743
	else 
marci@1383
   744
	  return backward_map[e]; 
marci@556
   745
      }
marci@556
   746
    };
marci@1383
   747
        
marci@1383
   748
    template <typename T>
klao@1909
   749
    class UEdgeMap {
klao@1909
   750
      template <typename TT> friend class UEdgeMap;
marci@1383
   751
      typename _Graph::template EdgeMap<T> map; 
marci@1383
   752
    public:
marci@1383
   753
      typedef T Value;
klao@1909
   754
      typedef UEdge Key;
marci@1383
   755
      
klao@1909
   756
      UEdgeMap(const UGraphAdaptorBase<_Graph>& g) : 
marci@1383
   757
	map(*(g.graph)) { }
marci@556
   758
klao@1909
   759
      UEdgeMap(const UGraphAdaptorBase<_Graph>& g, T a) : 
marci@1383
   760
	map(*(g.graph), a) { }
marci@1383
   761
      
klao@1909
   762
      void set(UEdge e, T a) { 
marci@1383
   763
	map.set(e, a); 
marci@1383
   764
      }
marci@556
   765
klao@1909
   766
      T operator[](UEdge e) const { 
marci@1383
   767
	return map[e]; 
marci@1383
   768
      }
marci@1383
   769
    };
marci@1383
   770
      
marci@1383
   771
  };
marci@1383
   772
klao@1951
   773
  ///\brief An undirected graph is made from a directed graph by an adaptor
klao@1951
   774
  ///\ingroup graph_adaptors
klao@1951
   775
  ///
klao@1951
   776
  /// Undocumented, untested!!!
klao@1951
   777
  /// If somebody knows nice demo application, let's polulate it.
klao@1951
   778
  /// 
klao@1951
   779
  /// \author Marton Makai
marci@1383
   780
  template<typename _Graph>
klao@1909
   781
  class UGraphAdaptor : 
klao@1909
   782
    public IterableUGraphExtender<
klao@1909
   783
    UGraphAdaptorBase<_Graph> > {
marci@1383
   784
  public:
marci@1383
   785
    typedef _Graph Graph;
klao@1909
   786
    typedef IterableUGraphExtender<
klao@1909
   787
      UGraphAdaptorBase<_Graph> > Parent;
marci@1383
   788
  protected:
klao@1909
   789
    UGraphAdaptor() { }
marci@1383
   790
  public:
klao@1909
   791
    UGraphAdaptor(_Graph& _graph) { 
marci@1383
   792
      setGraph(_graph);
marci@556
   793
    }
marci@556
   794
  };
marci@556
   795
marci@992
   796
  
marci@992
   797
  template <typename _Graph, 
marci@992
   798
	    typename ForwardFilterMap, typename BackwardFilterMap>
alpar@1401
   799
  class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
marci@992
   800
  public:
marci@992
   801
    typedef _Graph Graph;
alpar@1401
   802
    typedef GraphAdaptorBase<_Graph> Parent;
marci@992
   803
  protected:
marci@992
   804
    ForwardFilterMap* forward_filter;
marci@992
   805
    BackwardFilterMap* backward_filter;
alpar@1401
   806
    SubBidirGraphAdaptorBase() : Parent(), 
marci@992
   807
				 forward_filter(0), backward_filter(0) { }
marci@992
   808
marci@992
   809
    void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
marci@992
   810
      forward_filter=&_forward_filter;
marci@992
   811
    }
marci@992
   812
    void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
marci@992
   813
      backward_filter=&_backward_filter;
marci@992
   814
    }
marci@992
   815
marci@992
   816
  public:
alpar@1401
   817
//     SubGraphAdaptorBase(Graph& _graph, 
marci@992
   818
// 			NodeFilterMap& _node_filter_map, 
marci@992
   819
// 			EdgeFilterMap& _edge_filter_map) : 
marci@992
   820
//       Parent(&_graph), 
marci@992
   821
//       node_filter_map(&node_filter_map), 
marci@992
   822
//       edge_filter_map(&edge_filter_map) { }
marci@992
   823
marci@992
   824
    typedef typename Parent::Node Node;
marci@992
   825
    typedef typename _Graph::Edge GraphEdge;
marci@992
   826
    template <typename T> class EdgeMap;
alpar@1949
   827
    // SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from 
alpar@1949
   828
    // _Graph::Edge. It contains an extra bool flag which is true 
alpar@1949
   829
    // if and only if the 
alpar@1949
   830
    // edge is the backward version of the original edge.
marci@992
   831
    class Edge : public _Graph::Edge {
alpar@1401
   832
      friend class SubBidirGraphAdaptorBase<
marci@992
   833
	Graph, ForwardFilterMap, BackwardFilterMap>;
marci@992
   834
      template<typename T> friend class EdgeMap;
marci@992
   835
    protected:
marci@992
   836
      bool backward; //true, iff backward
marci@992
   837
    public:
marci@992
   838
      Edge() { }
alpar@1949
   839
      // \todo =false is needed, or causes problems?
alpar@1949
   840
      // If \c _backward is false, then we get an edge corresponding to the 
alpar@1949
   841
      // original one, otherwise its oppositely directed pair is obtained.
marci@992
   842
      Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) : 
marci@992
   843
	_Graph::Edge(e), backward(_backward) { }
marci@992
   844
      Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
marci@992
   845
      bool operator==(const Edge& v) const { 
marci@992
   846
	return (this->backward==v.backward && 
marci@992
   847
		static_cast<typename _Graph::Edge>(*this)==
marci@992
   848
		static_cast<typename _Graph::Edge>(v));
marci@992
   849
      } 
marci@992
   850
      bool operator!=(const Edge& v) const { 
marci@992
   851
	return (this->backward!=v.backward || 
marci@992
   852
		static_cast<typename _Graph::Edge>(*this)!=
marci@992
   853
		static_cast<typename _Graph::Edge>(v));
marci@992
   854
      }
marci@992
   855
    };
marci@992
   856
marci@992
   857
    void first(Node& i) const { 
marci@992
   858
      Parent::first(i); 
marci@992
   859
    }
marci@992
   860
marci@992
   861
    void first(Edge& i) const { 
marci@992
   862
      Parent::first(i); 
marci@992
   863
      i.backward=false;
marci@992
   864
      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   865
	     !(*forward_filter)[i]) Parent::next(i);
marci@992
   866
      if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   867
	Parent::first(i); 
marci@992
   868
	i.backward=true;
marci@992
   869
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   870
	       !(*backward_filter)[i]) Parent::next(i);
marci@992
   871
      }
marci@992
   872
    }
marci@992
   873
marci@992
   874
    void firstIn(Edge& i, const Node& n) const { 
marci@992
   875
      Parent::firstIn(i, n); 
marci@992
   876
      i.backward=false;
marci@992
   877
      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@1269
   878
	     !(*forward_filter)[i]) Parent::nextIn(i);
marci@992
   879
      if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   880
	Parent::firstOut(i, n); 
marci@992
   881
	i.backward=true;
marci@992
   882
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   883
	       !(*backward_filter)[i]) Parent::nextOut(i);
marci@992
   884
      }
marci@992
   885
    }
marci@992
   886
marci@992
   887
    void firstOut(Edge& i, const Node& n) const { 
marci@992
   888
      Parent::firstOut(i, n); 
marci@992
   889
      i.backward=false;
marci@992
   890
      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   891
	     !(*forward_filter)[i]) Parent::nextOut(i);
marci@992
   892
      if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   893
	Parent::firstIn(i, n); 
marci@992
   894
	i.backward=true;
marci@992
   895
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   896
	       !(*backward_filter)[i]) Parent::nextIn(i);
marci@992
   897
      }
marci@992
   898
    }
marci@992
   899
marci@992
   900
    void next(Node& i) const { 
marci@992
   901
      Parent::next(i); 
marci@992
   902
    }
marci@992
   903
marci@992
   904
    void next(Edge& i) const { 
marci@992
   905
      if (!(i.backward)) {
marci@992
   906
	Parent::next(i);
marci@992
   907
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   908
	       !(*forward_filter)[i]) Parent::next(i);
marci@992
   909
	if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   910
	  Parent::first(i); 
marci@992
   911
	  i.backward=true;
marci@992
   912
	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   913
		 !(*backward_filter)[i]) Parent::next(i);
marci@992
   914
	}
marci@992
   915
      } else {
marci@992
   916
	Parent::next(i);
marci@992
   917
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   918
	       !(*backward_filter)[i]) Parent::next(i);
marci@992
   919
      }
marci@992
   920
    }
marci@992
   921
marci@992
   922
    void nextIn(Edge& i) const { 
marci@992
   923
      if (!(i.backward)) {
marci@992
   924
	Node n=Parent::target(i);
marci@992
   925
	Parent::nextIn(i);
marci@992
   926
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   927
	       !(*forward_filter)[i]) Parent::nextIn(i);
marci@992
   928
	if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   929
	  Parent::firstOut(i, n); 
marci@992
   930
	  i.backward=true;
marci@992
   931
	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   932
		 !(*backward_filter)[i]) Parent::nextOut(i);
marci@992
   933
	}
marci@992
   934
      } else {
marci@992
   935
	Parent::nextOut(i);
marci@992
   936
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   937
	       !(*backward_filter)[i]) Parent::nextOut(i);
marci@992
   938
      }
marci@992
   939
    }
marci@992
   940
marci@992
   941
    void nextOut(Edge& i) const { 
marci@992
   942
      if (!(i.backward)) {
marci@992
   943
	Node n=Parent::source(i);
marci@992
   944
	Parent::nextOut(i);
marci@992
   945
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   946
	       !(*forward_filter)[i]) Parent::nextOut(i);
marci@992
   947
	if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   948
	  Parent::firstIn(i, n); 
marci@992
   949
	  i.backward=true;
marci@992
   950
	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   951
		 !(*backward_filter)[i]) Parent::nextIn(i);
marci@992
   952
	}
marci@992
   953
      } else {
marci@992
   954
	Parent::nextIn(i);
marci@992
   955
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   956
	       !(*backward_filter)[i]) Parent::nextIn(i);
marci@992
   957
      }
marci@992
   958
    }
marci@992
   959
marci@992
   960
    Node source(Edge e) const { 
marci@992
   961
      return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
marci@992
   962
    Node target(Edge e) const { 
marci@992
   963
      return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
marci@992
   964
klao@1951
   965
    /// Gives back the opposite edge.
alpar@1949
   966
klao@1951
   967
    ///\e
klao@1951
   968
    ///
marci@992
   969
    Edge opposite(const Edge& e) const { 
marci@992
   970
      Edge f=e;
marci@992
   971
      f.backward=!f.backward;
marci@992
   972
      return f;
marci@992
   973
    }
marci@992
   974
klao@1951
   975
    ///\e
alpar@1949
   976
klao@1951
   977
    /// \warning This is a linear time operation and works only if 
klao@1951
   978
    /// \c Graph::EdgeIt is defined.
klao@1951
   979
    /// \todo hmm
marci@992
   980
    int edgeNum() const { 
marci@992
   981
      int i=0;
marci@992
   982
      Edge e;
marci@992
   983
      for (first(e); e!=INVALID; next(e)) ++i;
marci@992
   984
      return i; 
marci@992
   985
    }
marci@992
   986
marci@992
   987
    bool forward(const Edge& e) const { return !e.backward; }
marci@992
   988
    bool backward(const Edge& e) const { return e.backward; }
marci@992
   989
klao@1951
   990
    ///\e
alpar@1949
   991
klao@1951
   992
    /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two 
klao@1951
   993
    /// _Graph::EdgeMap one for the forward edges and 
klao@1951
   994
    /// one for the backward edges.
marci@992
   995
    template <typename T>
marci@992
   996
    class EdgeMap {
marci@992
   997
      template <typename TT> friend class EdgeMap;
marci@992
   998
      typename _Graph::template EdgeMap<T> forward_map, backward_map; 
marci@992
   999
    public:
marci@992
  1000
      typedef T Value;
marci@992
  1001
      typedef Edge Key;
marci@992
  1002
alpar@1401
  1003
      EdgeMap(const SubBidirGraphAdaptorBase<_Graph, 
marci@992
  1004
	      ForwardFilterMap, BackwardFilterMap>& g) : 
marci@992
  1005
	forward_map(*(g.graph)), backward_map(*(g.graph)) { }
marci@992
  1006
alpar@1401
  1007
      EdgeMap(const SubBidirGraphAdaptorBase<_Graph, 
marci@992
  1008
	      ForwardFilterMap, BackwardFilterMap>& g, T a) : 
marci@992
  1009
	forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
marci@992
  1010
      
marci@992
  1011
      void set(Edge e, T a) { 
marci@992
  1012
	if (!e.backward) 
marci@992
  1013
	  forward_map.set(e, a); 
marci@992
  1014
	else 
marci@992
  1015
	  backward_map.set(e, a); 
marci@992
  1016
      }
marci@992
  1017
marci@992
  1018
//       typename _Graph::template EdgeMap<T>::ConstReference 
marci@992
  1019
//       operator[](Edge e) const { 
marci@992
  1020
// 	if (!e.backward) 
marci@992
  1021
// 	  return forward_map[e]; 
marci@992
  1022
// 	else 
marci@992
  1023
// 	  return backward_map[e]; 
marci@992
  1024
//       }
marci@992
  1025
marci@992
  1026
//      typename _Graph::template EdgeMap<T>::Reference 
marci@1016
  1027
      T operator[](Edge e) const { 
marci@992
  1028
	if (!e.backward) 
marci@992
  1029
	  return forward_map[e]; 
marci@992
  1030
	else 
marci@992
  1031
	  return backward_map[e]; 
marci@992
  1032
      }
marci@992
  1033
marci@992
  1034
      void update() { 
marci@992
  1035
	forward_map.update(); 
marci@992
  1036
	backward_map.update();
marci@992
  1037
      }
marci@992
  1038
    };
marci@992
  1039
marci@992
  1040
  };
marci@569
  1041
marci@650
  1042
klao@1951
  1043
  ///\brief An adaptor for composing a subgraph of a 
klao@1951
  1044
  /// bidirected graph made from a directed one. 
klao@1951
  1045
  ///\ingroup graph_adaptors
klao@1951
  1046
  ///
klao@1951
  1047
  /// An adaptor for composing a subgraph of a 
klao@1951
  1048
  /// bidirected graph made from a directed one. 
klao@1951
  1049
  ///
klao@1951
  1050
  ///\warning Graph adaptors are in even more experimental state
klao@1951
  1051
  ///than the other
klao@1951
  1052
  ///parts of the lib. Use them at you own risk.
klao@1951
  1053
  ///
klao@1952
  1054
  /// Let \f$ G=(V, A) \f$ be a directed graph and for each directed edge 
klao@1952
  1055
  ///\f$ e\in A \f$, let \f$ \bar e \f$ denote the edge obtained by
klao@1951
  1056
  /// reversing its orientation. We are given moreover two bool valued 
klao@1951
  1057
  /// maps on the edge-set, 
klao@1952
  1058
  ///\f$ forward\_filter \f$, and \f$ backward\_filter \f$. 
klao@1951
  1059
  /// SubBidirGraphAdaptor implements the graph structure with node-set 
klao@1952
  1060
  ///\f$ V \f$ and edge-set 
klao@1952
  1061
  ///\f$ \{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\} \f$. 
klao@1951
  1062
  /// The purpose of writing + instead of union is because parallel 
klao@1951
  1063
  /// edges can arise. (Similarly, antiparallel edges also can arise).
klao@1951
  1064
  /// In other words, a subgraph of the bidirected graph obtained, which 
klao@1951
  1065
  /// is given by orienting the edges of the original graph in both directions.
klao@1951
  1066
  /// As the oppositely directed edges are logically different, 
klao@1951
  1067
  /// the maps are able to attach different values for them. 
klao@1951
  1068
  ///
klao@1951
  1069
  /// An example for such a construction is \c RevGraphAdaptor where the 
klao@1951
  1070
  /// forward_filter is everywhere false and the backward_filter is 
klao@1951
  1071
  /// everywhere true. We note that for sake of efficiency, 
klao@1951
  1072
  /// \c RevGraphAdaptor is implemented in a different way. 
klao@1951
  1073
  /// But BidirGraphAdaptor is obtained from 
klao@1951
  1074
  /// SubBidirGraphAdaptor by considering everywhere true 
klao@1951
  1075
  /// valued maps both for forward_filter and backward_filter. 
klao@1951
  1076
  ///
klao@1951
  1077
  /// The most important application of SubBidirGraphAdaptor 
klao@1951
  1078
  /// is ResGraphAdaptor, which stands for the residual graph in directed 
klao@1951
  1079
  /// flow and circulation problems. 
klao@1951
  1080
  /// As adaptors usually, the SubBidirGraphAdaptor implements the 
klao@1951
  1081
  /// above mentioned graph structure without its physical storage, 
klao@1951
  1082
  /// that is the whole stuff is stored in constant memory. 
marci@992
  1083
  template<typename _Graph, 
marci@650
  1084
	   typename ForwardFilterMap, typename BackwardFilterMap>
alpar@1401
  1085
  class SubBidirGraphAdaptor : 
marci@992
  1086
    public IterableGraphExtender<
alpar@1401
  1087
    SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
marci@650
  1088
  public:
marci@992
  1089
    typedef _Graph Graph;
marci@992
  1090
    typedef IterableGraphExtender<
alpar@1401
  1091
      SubBidirGraphAdaptorBase<
marci@992
  1092
      _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
marci@569
  1093
  protected:
alpar@1401
  1094
    SubBidirGraphAdaptor() { }
marci@992
  1095
  public:
alpar@1401
  1096
    SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter, 
marci@992
  1097
			 BackwardFilterMap& _backward_filter) { 
marci@992
  1098
      setGraph(_graph);
marci@992
  1099
      setForwardFilterMap(_forward_filter);
marci@992
  1100
      setBackwardFilterMap(_backward_filter);
marci@992
  1101
    }
marci@992
  1102
  };
marci@650
  1103
marci@569
  1104
marci@650
  1105
klao@1951
  1106
  ///\brief An adaptor for composing bidirected graph from a directed one. 
klao@1951
  1107
  ///\ingroup graph_adaptors
klao@1951
  1108
  ///
klao@1951
  1109
  ///\warning Graph adaptors are in even more experimental state
klao@1951
  1110
  ///than the other
klao@1951
  1111
  ///parts of the lib. Use them at you own risk.
klao@1951
  1112
  ///
klao@1951
  1113
  /// An adaptor for composing bidirected graph from a directed one. 
klao@1951
  1114
  /// A bidirected graph is composed over the directed one without physical 
klao@1951
  1115
  /// storage. As the oppositely directed edges are logically different ones 
klao@1951
  1116
  /// the maps are able to attach different values for them.
marci@650
  1117
  template<typename Graph>
alpar@1401
  1118
  class BidirGraphAdaptor : 
alpar@1401
  1119
    public SubBidirGraphAdaptor<
marci@650
  1120
    Graph, 
marci@650
  1121
    ConstMap<typename Graph::Edge, bool>, 
marci@650
  1122
    ConstMap<typename Graph::Edge, bool> > {
marci@650
  1123
  public:
alpar@1401
  1124
    typedef  SubBidirGraphAdaptor<
marci@650
  1125
      Graph, 
marci@650
  1126
      ConstMap<typename Graph::Edge, bool>, 
marci@650
  1127
      ConstMap<typename Graph::Edge, bool> > Parent; 
marci@650
  1128
  protected:
marci@650
  1129
    ConstMap<typename Graph::Edge, bool> cm;
marci@650
  1130
alpar@1401
  1131
    BidirGraphAdaptor() : Parent(), cm(true) { 
marci@655
  1132
      Parent::setForwardFilterMap(cm);
marci@655
  1133
      Parent::setBackwardFilterMap(cm);
marci@655
  1134
    }
marci@650
  1135
  public:
alpar@1401
  1136
    BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) { 
marci@650
  1137
      Parent::setGraph(_graph);
marci@650
  1138
      Parent::setForwardFilterMap(cm);
marci@650
  1139
      Parent::setBackwardFilterMap(cm);
marci@650
  1140
    }
marci@738
  1141
marci@738
  1142
    int edgeNum() const { 
marci@738
  1143
      return 2*this->graph->edgeNum();
marci@738
  1144
    }
marci@650
  1145
  };
marci@650
  1146
marci@650
  1147
marci@650
  1148
  template<typename Graph, typename Number,
marci@650
  1149
	   typename CapacityMap, typename FlowMap>
marci@658
  1150
  class ResForwardFilter {
marci@658
  1151
    //    const Graph* graph;
marci@650
  1152
    const CapacityMap* capacity;
marci@650
  1153
    const FlowMap* flow;
marci@650
  1154
  public:
marci@658
  1155
    ResForwardFilter(/*const Graph& _graph, */
marci@658
  1156
		     const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1157
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1158
    ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@656
  1159
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1160
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1161
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1162
      return (Number((*flow)[e]) < Number((*capacity)[e]));
marci@650
  1163
    }
marci@650
  1164
  };
marci@650
  1165
marci@650
  1166
  template<typename Graph, typename Number,
marci@650
  1167
	   typename CapacityMap, typename FlowMap>
marci@658
  1168
  class ResBackwardFilter {
marci@650
  1169
    const CapacityMap* capacity;
marci@650
  1170
    const FlowMap* flow;
marci@650
  1171
  public:
marci@658
  1172
    ResBackwardFilter(/*const Graph& _graph,*/ 
marci@658
  1173
		      const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1174
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1175
    ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@656
  1176
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1177
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1178
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1179
      return (Number(0) < Number((*flow)[e]));
marci@650
  1180
    }
marci@650
  1181
  };
marci@650
  1182
marci@653
  1183
  
klao@1951
  1184
  ///\brief An adaptor for composing the residual
klao@1951
  1185
  ///graph for directed flow and circulation problems.
klao@1951
  1186
  ///\ingroup graph_adaptors
klao@1951
  1187
  ///
klao@1951
  1188
  ///An adaptor for composing the residual graph for
klao@1951
  1189
  ///directed flow and circulation problems. 
klao@1952
  1190
  ///Let \f$ G=(V, A) \f$ be a directed graph and let \f$ F \f$ be a 
klao@1951
  1191
  ///number type. Let moreover 
klao@1952
  1192
  ///\f$ f,c:A\to F \f$, be functions on the edge-set. 
klao@1952
  1193
  ///In the appications of ResGraphAdaptor, \f$ f \f$ usually stands for a flow 
klao@1952
  1194
  ///and \f$ c \f$ for a capacity function.   
klao@1951
  1195
  ///Suppose that a graph instange \c g of type 
klao@1952
  1196
  ///\c ListGraph implements \f$ G \f$.
klao@1951
  1197
  ///\code
klao@1951
  1198
  ///  ListGraph g;
klao@1951
  1199
  ///\endcode
klao@1951
  1200
  ///Then RevGraphAdaptor implements the graph structure with node-set 
klao@1952
  1201
  ///\f$ V \f$ and edge-set \f$ A_{forward}\cup A_{backward} \f$, where 
klao@1952
  1202
  ///\f$ A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\} \f$ and 
klao@1952
  1203
  ///\f$ A_{backward}=\{vu : uv\in A, f(uv)>0\} \f$, 
klao@1951
  1204
  ///i.e. the so called residual graph. 
klao@1952
  1205
  ///When we take the union \f$ A_{forward}\cup A_{backward} \f$, 
klao@1951
  1206
  ///multilicities are counted, i.e. if an edge is in both 
klao@1952
  1207
  ///\f$ A_{forward} \f$ and \f$ A_{backward} \f$, then in the adaptor it 
klao@1951
  1208
  ///appears twice. 
klao@1951
  1209
  ///The following code shows how 
klao@1951
  1210
  ///such an instance can be constructed.
klao@1951
  1211
  ///\code
klao@1951
  1212
  ///typedef ListGraph Graph;
klao@1951
  1213
  ///Graph::EdgeMap<int> f(g);
klao@1951
  1214
  ///Graph::EdgeMap<int> c(g);
klao@1951
  1215
  ///ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
klao@1951
  1216
  ///\endcode
klao@1951
  1217
  ///\author Marton Makai
klao@1951
  1218
  ///
marci@650
  1219
  template<typename Graph, typename Number, 
marci@650
  1220
	   typename CapacityMap, typename FlowMap>
alpar@1401
  1221
  class ResGraphAdaptor : 
alpar@1401
  1222
    public SubBidirGraphAdaptor< 
marci@650
  1223
    Graph, 
marci@658
  1224
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1225
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
marci@650
  1226
  public:
alpar@1401
  1227
    typedef SubBidirGraphAdaptor< 
marci@650
  1228
      Graph, 
marci@658
  1229
      ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1230
      ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
marci@650
  1231
  protected:
marci@650
  1232
    const CapacityMap* capacity;
marci@650
  1233
    FlowMap* flow;
marci@658
  1234
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
marci@658
  1235
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
alpar@1401
  1236
    ResGraphAdaptor() : Parent(), 
marci@658
  1237
 			capacity(0), flow(0) { }
marci@658
  1238
    void setCapacityMap(const CapacityMap& _capacity) {
marci@658
  1239
      capacity=&_capacity;
marci@658
  1240
      forward_filter.setCapacity(_capacity);
marci@658
  1241
      backward_filter.setCapacity(_capacity);
marci@658
  1242
    }
marci@658
  1243
    void setFlowMap(FlowMap& _flow) {
marci@658
  1244
      flow=&_flow;
marci@658
  1245
      forward_filter.setFlow(_flow);
marci@658
  1246
      backward_filter.setFlow(_flow);
marci@658
  1247
    }
marci@650
  1248
  public:
alpar@1401
  1249
    ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity, 
marci@650
  1250
		       FlowMap& _flow) : 
marci@650
  1251
      Parent(), capacity(&_capacity), flow(&_flow), 
marci@658
  1252
      forward_filter(/*_graph,*/ _capacity, _flow), 
marci@658
  1253
      backward_filter(/*_graph,*/ _capacity, _flow) {
marci@650
  1254
      Parent::setGraph(_graph);
marci@650
  1255
      Parent::setForwardFilterMap(forward_filter);
marci@650
  1256
      Parent::setBackwardFilterMap(backward_filter);
marci@650
  1257
    }
marci@650
  1258
marci@660
  1259
    typedef typename Parent::Edge Edge;
marci@660
  1260
marci@660
  1261
    void augment(const Edge& e, Number a) const {
marci@650
  1262
      if (Parent::forward(e))  
marci@650
  1263
	flow->set(e, (*flow)[e]+a);
marci@650
  1264
      else  
marci@650
  1265
	flow->set(e, (*flow)[e]-a);
marci@650
  1266
    }
marci@650
  1267
klao@1951
  1268
    /// \brief Residual capacity map.
klao@1951
  1269
    ///
klao@1951
  1270
    /// In generic residual graphs the residual capacity can be obtained 
klao@1951
  1271
    /// as a map. 
marci@660
  1272
    class ResCap {
marci@660
  1273
    protected:
alpar@1401
  1274
      const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
marci@660
  1275
    public:
alpar@987
  1276
      typedef Number Value;
alpar@987
  1277
      typedef Edge Key;
alpar@1401
  1278
      ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>& 
marci@888
  1279
	     _res_graph) : res_graph(&_res_graph) { }
marci@660
  1280
      Number operator[](const Edge& e) const { 
marci@660
  1281
	if (res_graph->forward(e)) 
marci@660
  1282
	  return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; 
marci@660
  1283
	else 
marci@660
  1284
	  return (*(res_graph->flow))[e]; 
marci@660
  1285
      }
marci@660
  1286
    };
marci@660
  1287
alpar@1401
  1288
    //    KEEP_MAPS(Parent, ResGraphAdaptor);
marci@650
  1289
  };
marci@650
  1290
marci@650
  1291
marci@998
  1292
marci@998
  1293
  template <typename _Graph, typename FirstOutEdgesMap>
alpar@1401
  1294
  class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
marci@998
  1295
  public:
marci@998
  1296
    typedef _Graph Graph;
alpar@1401
  1297
    typedef GraphAdaptorBase<_Graph> Parent;
marci@998
  1298
  protected:
marci@998
  1299
    FirstOutEdgesMap* first_out_edges;
alpar@1401
  1300
    ErasingFirstGraphAdaptorBase() : Parent(), 
marci@998
  1301
				     first_out_edges(0) { }
marci@998
  1302
marci@998
  1303
    void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
marci@998
  1304
      first_out_edges=&_first_out_edges;
marci@998
  1305
    }
marci@998
  1306
marci@998
  1307
  public:
marci@998
  1308
marci@998
  1309
    typedef typename Parent::Node Node;
marci@998
  1310
    typedef typename Parent::Edge Edge;
marci@998
  1311
marci@998
  1312
    void firstOut(Edge& i, const Node& n) const { 
marci@998
  1313
      i=(*first_out_edges)[n];
marci@998
  1314
    }
marci@998
  1315
marci@998
  1316
    void erase(const Edge& e) const {
marci@998
  1317
      Node n=source(e);
marci@998
  1318
      Edge f=e;
marci@998
  1319
      Parent::nextOut(f);
marci@998
  1320
      first_out_edges->set(n, f);
marci@998
  1321
    }    
marci@998
  1322
  };
marci@998
  1323
marci@998
  1324
klao@1951
  1325
  ///\brief For blocking flows.
klao@1951
  1326
  ///\ingroup graph_adaptors
klao@1951
  1327
  ///
klao@1951
  1328
  ///\warning Graph adaptors are in even more
klao@1951
  1329
  ///experimental state than the other
klao@1951
  1330
  ///parts of the lib. Use them at you own risk.
klao@1951
  1331
  ///
klao@1951
  1332
  ///This graph adaptor is used for on-the-fly 
klao@1951
  1333
  ///Dinits blocking flow computations.
klao@1951
  1334
  ///For each node, an out-edge is stored which is used when the 
klao@1951
  1335
  ///\code
klao@1951
  1336
  ///OutEdgeIt& first(OutEdgeIt&, const Node&)
klao@1951
  1337
  ///\endcode
klao@1951
  1338
  ///is called. 
klao@1951
  1339
  ///
klao@1951
  1340
  ///\author Marton Makai
klao@1951
  1341
  ///
marci@998
  1342
  template <typename _Graph, typename FirstOutEdgesMap>
alpar@1401
  1343
  class ErasingFirstGraphAdaptor : 
marci@998
  1344
    public IterableGraphExtender<
alpar@1401
  1345
    ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
marci@650
  1346
  public:
marci@998
  1347
    typedef _Graph Graph;
marci@998
  1348
    typedef IterableGraphExtender<
alpar@1401
  1349
      ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
alpar@1401
  1350
    ErasingFirstGraphAdaptor(Graph& _graph, 
marci@998
  1351
			     FirstOutEdgesMap& _first_out_edges) { 
marci@998
  1352
      setGraph(_graph);
marci@998
  1353
      setFirstOutEdgesMap(_first_out_edges);
marci@998
  1354
    } 
marci@1019
  1355
marci@998
  1356
  };
marci@556
  1357
deba@1472
  1358
  template <typename _Graph>
deba@1697
  1359
  class SplitGraphAdaptorBase 
deba@1697
  1360
    : public GraphAdaptorBase<_Graph> {
deba@1697
  1361
  public:
deba@1697
  1362
    typedef GraphAdaptorBase<_Graph> Parent;
deba@1697
  1363
deba@1697
  1364
    class Node;
deba@1697
  1365
    class Edge;
deba@1697
  1366
    template <typename T> class NodeMap;
deba@1697
  1367
    template <typename T> class EdgeMap;
deba@1697
  1368
    
deba@1697
  1369
deba@1697
  1370
    class Node : public Parent::Node {
deba@1697
  1371
      friend class SplitGraphAdaptorBase;
deba@1697
  1372
      template <typename T> friend class NodeMap;
deba@1697
  1373
      typedef typename Parent::Node NodeParent;
deba@1697
  1374
    private:
deba@1697
  1375
deba@1697
  1376
      bool entry;
deba@1697
  1377
      Node(typename Parent::Node _node, bool _entry)
deba@1697
  1378
	: Parent::Node(_node), entry(_entry) {}
deba@1697
  1379
      
deba@1697
  1380
    public:
deba@1697
  1381
      Node() {}
deba@1697
  1382
      Node(Invalid) : NodeParent(INVALID), entry(true) {}
deba@1697
  1383
deba@1697
  1384
      bool operator==(const Node& node) const {
deba@1697
  1385
	return NodeParent::operator==(node) && entry == node.entry;
deba@1697
  1386
      }
deba@1697
  1387
      
deba@1697
  1388
      bool operator!=(const Node& node) const {
deba@1697
  1389
	return !(*this == node);
deba@1697
  1390
      }
deba@1697
  1391
      
deba@1697
  1392
      bool operator<(const Node& node) const {
deba@1697
  1393
	return NodeParent::operator<(node) || 
deba@1697
  1394
	  (NodeParent::operator==(node) && entry < node.entry);
deba@1697
  1395
      }
deba@1697
  1396
    };
deba@1697
  1397
klao@1951
  1398
    /// \todo May we want VARIANT/union type
deba@1697
  1399
    class Edge : public Parent::Edge {
deba@1697
  1400
      friend class SplitGraphAdaptorBase;
deba@1697
  1401
      template <typename T> friend class EdgeMap;
deba@1697
  1402
    private:
deba@1697
  1403
      typedef typename Parent::Edge EdgeParent;
deba@1697
  1404
      typedef typename Parent::Node NodeParent;
deba@1697
  1405
      NodeParent bind;
deba@1697
  1406
deba@1697
  1407
      Edge(const EdgeParent& edge, const NodeParent& node)
deba@1697
  1408
	: EdgeParent(edge), bind(node) {}
deba@1697
  1409
    public:
deba@1697
  1410
      Edge() {}
deba@1697
  1411
      Edge(Invalid) : EdgeParent(INVALID), bind(INVALID) {}
deba@1697
  1412
deba@1697
  1413
      bool operator==(const Edge& edge) const {
deba@1697
  1414
	return EdgeParent::operator==(edge) && bind == edge.bind;
deba@1697
  1415
      }
deba@1697
  1416
      
deba@1697
  1417
      bool operator!=(const Edge& edge) const {
deba@1697
  1418
	return !(*this == edge);
deba@1697
  1419
      }
deba@1697
  1420
      
deba@1697
  1421
      bool operator<(const Edge& edge) const {
deba@1697
  1422
	return EdgeParent::operator<(edge) || 
deba@1697
  1423
	  (EdgeParent::operator==(edge) && bind < edge.bind);
deba@1697
  1424
      }
deba@1697
  1425
    };
deba@1697
  1426
deba@1697
  1427
    void first(Node& node) const {
deba@1697
  1428
      Parent::first(node);
deba@1697
  1429
      node.entry = true;
deba@1697
  1430
    } 
deba@1697
  1431
deba@1697
  1432
    void next(Node& node) const {
deba@1697
  1433
      if (node.entry) {
deba@1697
  1434
	node.entry = false;
deba@1697
  1435
      } else {
deba@1697
  1436
	node.entry = true;
deba@1697
  1437
	Parent::next(node);
deba@1697
  1438
      }
deba@1697
  1439
    }
deba@1697
  1440
deba@1697
  1441
    void first(Edge& edge) const {
deba@1697
  1442
      Parent::first(edge);
deba@1697
  1443
      if ((typename Parent::Edge&)edge == INVALID) {
deba@1697
  1444
	Parent::first(edge.bind);
deba@1697
  1445
      } else {
deba@1697
  1446
	edge.bind = INVALID;
deba@1697
  1447
      }
deba@1697
  1448
    }
deba@1697
  1449
deba@1697
  1450
    void next(Edge& edge) const {
deba@1697
  1451
      if ((typename Parent::Edge&)edge != INVALID) {
deba@1697
  1452
	Parent::next(edge);
deba@1697
  1453
	if ((typename Parent::Edge&)edge == INVALID) {
deba@1697
  1454
	  Parent::first(edge.bind);
deba@1697
  1455
	}
deba@1697
  1456
      } else {
deba@1697
  1457
	Parent::next(edge.bind);
deba@1697
  1458
      }      
deba@1697
  1459
    }
deba@1697
  1460
deba@1697
  1461
    void firstIn(Edge& edge, const Node& node) const {
deba@1697
  1462
      if (node.entry) {
deba@1697
  1463
	Parent::firstIn(edge, node);
deba@1697
  1464
	edge.bind = INVALID;
deba@1697
  1465
      } else {
deba@1697
  1466
	(typename Parent::Edge&)edge = INVALID;
deba@1697
  1467
	edge.bind = node;
deba@1697
  1468
      }
deba@1697
  1469
    }
deba@1697
  1470
deba@1697
  1471
    void nextIn(Edge& edge) const {
deba@1697
  1472
      if ((typename Parent::Edge&)edge != INVALID) {
deba@1697
  1473
	Parent::nextIn(edge);
deba@1697
  1474
      } else {
deba@1697
  1475
	edge.bind = INVALID;
deba@1697
  1476
      }      
deba@1697
  1477
    }
deba@1697
  1478
deba@1697
  1479
    void firstOut(Edge& edge, const Node& node) const {
deba@1697
  1480
      if (!node.entry) {
deba@1697
  1481
	Parent::firstOut(edge, node);
deba@1697
  1482
	edge.bind = INVALID;
deba@1697
  1483
      } else {
deba@1697
  1484
	(typename Parent::Edge&)edge = INVALID;
deba@1697
  1485
	edge.bind = node;
deba@1697
  1486
      }
deba@1697
  1487
    }
deba@1697
  1488
deba@1697
  1489
    void nextOut(Edge& edge) const {
deba@1697
  1490
      if ((typename Parent::Edge&)edge != INVALID) {
deba@1697
  1491
	Parent::nextOut(edge);
deba@1697
  1492
      } else {
deba@1697
  1493
	edge.bind = INVALID;
deba@1697
  1494
      }
deba@1697
  1495
    }
deba@1697
  1496
deba@1697
  1497
    Node source(const Edge& edge) const {
deba@1697
  1498
      if ((typename Parent::Edge&)edge != INVALID) {
deba@1697
  1499
	return Node(Parent::source(edge), false);
deba@1697
  1500
      } else {
deba@1697
  1501
	return Node(edge.bind, true);
deba@1697
  1502
      }
deba@1697
  1503
    }
deba@1697
  1504
deba@1697
  1505
    Node target(const Edge& edge) const {
deba@1697
  1506
      if ((typename Parent::Edge&)edge != INVALID) {
deba@1697
  1507
	return Node(Parent::target(edge), true);
deba@1697
  1508
      } else {
deba@1697
  1509
	return Node(edge.bind, false);
deba@1697
  1510
      }
deba@1697
  1511
    }
deba@1697
  1512
deba@1697
  1513
    static bool entryNode(const Node& node) {
deba@1697
  1514
      return node.entry;
deba@1697
  1515
    }
deba@1697
  1516
deba@1697
  1517
    static bool exitNode(const Node& node) {
deba@1697
  1518
      return !node.entry;
deba@1697
  1519
    }
deba@1697
  1520
deba@1697
  1521
    static Node getEntry(const typename Parent::Node& node) {
deba@1697
  1522
      return Node(node, true);
deba@1697
  1523
    }
deba@1697
  1524
deba@1697
  1525
    static Node getExit(const typename Parent::Node& node) {
deba@1697
  1526
      return Node(node, false);
deba@1697
  1527
    }
deba@1697
  1528
deba@1697
  1529
    static bool originalEdge(const Edge& edge) {
deba@1697
  1530
      return (typename Parent::Edge&)edge != INVALID;
deba@1697
  1531
    }
deba@1697
  1532
deba@1697
  1533
    static bool bindingEdge(const Edge& edge) {
deba@1697
  1534
      return edge.bind != INVALID;
deba@1697
  1535
    }
deba@1697
  1536
deba@1697
  1537
    static Node getBindedNode(const Edge& edge) {
deba@1697
  1538
      return edge.bind;
deba@1697
  1539
    }
deba@1697
  1540
deba@1697
  1541
    int nodeNum() const {
deba@1697
  1542
      return Parent::nodeNum() * 2;
deba@1697
  1543
    }
deba@1697
  1544
deba@1697
  1545
    typedef CompileTimeAnd<typename Parent::NodeNumTag, 
deba@1697
  1546
    			   typename Parent::EdgeNumTag> EdgeNumTag;
deba@1697
  1547
    
deba@1697
  1548
    int edgeNum() const {
deba@1697
  1549
      return Parent::edgeNum() + Parent::nodeNum();
deba@1697
  1550
    }
deba@1697
  1551
deba@1697
  1552
    Edge findEdge(const Node& source, const Node& target, 
deba@1697
  1553
		  const Edge& prev = INVALID) const {
deba@1697
  1554
      if (exitNode(source) && entryNode(target)) {
deba@1697
  1555
	return Parent::findEdge(source, target, prev);
deba@1697
  1556
      } else {
deba@1697
  1557
	if (prev == INVALID && entryNode(source) && exitNode(target) && 
deba@1697
  1558
	    (typename Parent::Node&)source == (typename Parent::Node&)target) {
deba@1697
  1559
	  return Edge(INVALID, source);
deba@1697
  1560
	} else {
deba@1697
  1561
	  return INVALID;
deba@1697
  1562
	}
deba@1697
  1563
      }
deba@1697
  1564
    }
deba@1697
  1565
    
deba@1697
  1566
    template <typename T>
deba@1697
  1567
    class NodeMap : public MapBase<Node, T> {
deba@1697
  1568
      typedef typename Parent::template NodeMap<T> NodeImpl;
deba@1697
  1569
    public:
deba@1697
  1570
      NodeMap(const SplitGraphAdaptorBase& _graph) 
deba@1697
  1571
	: entry(_graph), exit(_graph) {}
deba@1697
  1572
      NodeMap(const SplitGraphAdaptorBase& _graph, const T& t) 
deba@1697
  1573
	: entry(_graph, t), exit(_graph, t) {}
deba@1697
  1574
      
deba@1697
  1575
      void set(const Node& key, const T& val) {
deba@1697
  1576
	if (key.entry) { entry.set(key, val); }
deba@1697
  1577
	else {exit.set(key, val); }
deba@1697
  1578
      }
deba@1697
  1579
      
deba@1725
  1580
      typename MapTraits<NodeImpl>::ReturnValue 
deba@1697
  1581
      operator[](const Node& key) {
deba@1697
  1582
	if (key.entry) { return entry[key]; }
deba@1697
  1583
	else { return exit[key]; }
deba@1697
  1584
      }
deba@1697
  1585
deba@1725
  1586
      typename MapTraits<NodeImpl>::ConstReturnValue
deba@1725
  1587
      operator[](const Node& key) const {
deba@1697
  1588
	if (key.entry) { return entry[key]; }
deba@1697
  1589
	else { return exit[key]; }
deba@1697
  1590
      }
deba@1697
  1591
deba@1697
  1592
    private:
deba@1697
  1593
      NodeImpl entry, exit;
deba@1697
  1594
    };
deba@1697
  1595
deba@1697
  1596
    template <typename T>
deba@1697
  1597
    class EdgeMap : public MapBase<Edge, T> {
deba@1697
  1598
      typedef typename Parent::template NodeMap<T> NodeImpl;
deba@1697
  1599
      typedef typename Parent::template EdgeMap<T> EdgeImpl;
deba@1697
  1600
    public:
deba@1697
  1601
      EdgeMap(const SplitGraphAdaptorBase& _graph) 
deba@1697
  1602
	: bind(_graph), orig(_graph) {}
deba@1697
  1603
      EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t) 
deba@1697
  1604
	: bind(_graph, t), orig(_graph, t) {}
deba@1697
  1605
      
deba@1697
  1606
      void set(const Edge& key, const T& val) {
deba@1697
  1607
	if ((typename Parent::Edge&)key != INVALID) { orig.set(key, val); }
deba@1697
  1608
	else {bind.set(key.bind, val); }
deba@1697
  1609
      }
deba@1697
  1610
      
deba@1725
  1611
      typename MapTraits<EdgeImpl>::ReturnValue
deba@1697
  1612
      operator[](const Edge& key) {
deba@1697
  1613
	if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
deba@1697
  1614
	else {return bind[key.bind]; }
deba@1697
  1615
      }
deba@1697
  1616
deba@1725
  1617
      typename MapTraits<EdgeImpl>::ConstReturnValue
deba@1725
  1618
      operator[](const Edge& key) const {
deba@1697
  1619
	if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
deba@1697
  1620
	else {return bind[key.bind]; }
deba@1697
  1621
      }
deba@1697
  1622
deba@1697
  1623
    private:
deba@1697
  1624
      typename Parent::template NodeMap<T> bind;
deba@1697
  1625
      typename Parent::template EdgeMap<T> orig;
deba@1697
  1626
    };
deba@1697
  1627
deba@1697
  1628
    template <typename EntryMap, typename ExitMap>
deba@1697
  1629
    class CombinedNodeMap : public MapBase<Node, typename EntryMap::Value> {
deba@1697
  1630
    public:
deba@1697
  1631
      typedef MapBase<Node, typename EntryMap::Value> Parent;
deba@1697
  1632
deba@1697
  1633
      typedef typename Parent::Key Key;
deba@1697
  1634
      typedef typename Parent::Value Value;
deba@1697
  1635
deba@1697
  1636
      CombinedNodeMap(EntryMap& _entryMap, ExitMap& _exitMap) 
deba@1697
  1637
	: entryMap(_entryMap), exitMap(_exitMap) {}
deba@1697
  1638
deba@1697
  1639
      Value& operator[](const Key& key) {
deba@1697
  1640
	if (key.entry) {
deba@1697
  1641
	  return entryMap[key];
deba@1697
  1642
	} else {
deba@1697
  1643
	  return exitMap[key];
deba@1697
  1644
	}
deba@1697
  1645
      }
deba@1697
  1646
deba@1697
  1647
      Value operator[](const Key& key) const {
deba@1697
  1648
	if (key.entry) {
deba@1697
  1649
	  return entryMap[key];
deba@1697
  1650
	} else {
deba@1697
  1651
	  return exitMap[key];
deba@1697
  1652
	}
deba@1697
  1653
      }
deba@1697
  1654
deba@1697
  1655
      void set(const Key& key, const Value& value) {
deba@1697
  1656
	if (key.entry) {
deba@1697
  1657
	  entryMap.set(key, value);
deba@1697
  1658
	} else {
deba@1697
  1659
	  exitMap.set(key, value);
deba@1697
  1660
	}
deba@1697
  1661
      }
deba@1697
  1662
      
deba@1697
  1663
    private:
deba@1697
  1664
      
deba@1697
  1665
      EntryMap& entryMap;
deba@1697
  1666
      ExitMap& exitMap;
deba@1697
  1667
      
deba@1697
  1668
    };
deba@1697
  1669
deba@1697
  1670
    template <typename EdgeMap, typename NodeMap>
deba@1697
  1671
    class CombinedEdgeMap : public MapBase<Edge, typename EdgeMap::Value> {
deba@1697
  1672
    public:
deba@1697
  1673
      typedef MapBase<Edge, typename EdgeMap::Value> Parent;
deba@1697
  1674
deba@1697
  1675
      typedef typename Parent::Key Key;
deba@1697
  1676
      typedef typename Parent::Value Value;
deba@1697
  1677
deba@1697
  1678
      CombinedEdgeMap(EdgeMap& _edgeMap, NodeMap& _nodeMap) 
deba@1697
  1679
	: edgeMap(_edgeMap), nodeMap(_nodeMap) {}
deba@1697
  1680
deba@1697
  1681
      void set(const Edge& edge, const Value& val) {
deba@1697
  1682
	if (SplitGraphAdaptorBase::originalEdge(edge)) {
deba@1697
  1683
	  edgeMap.set(edge, val);
deba@1697
  1684
	} else {
deba@1697
  1685
	  nodeMap.set(SplitGraphAdaptorBase::bindedNode(edge), val);
deba@1697
  1686
	}
deba@1697
  1687
      }
deba@1697
  1688
deba@1697
  1689
      Value operator[](const Key& edge) const {
deba@1697
  1690
	if (SplitGraphAdaptorBase::originalEdge(edge)) {
deba@1697
  1691
	  return edgeMap[edge];
deba@1697
  1692
	} else {
deba@1697
  1693
	  return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
deba@1697
  1694
	}
deba@1697
  1695
      }      
deba@1697
  1696
deba@1697
  1697
      Value& operator[](const Key& edge) {
deba@1697
  1698
	if (SplitGraphAdaptorBase::originalEdge(edge)) {
deba@1697
  1699
	  return edgeMap[edge];
deba@1697
  1700
	} else {
deba@1697
  1701
	  return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
deba@1697
  1702
	}
deba@1697
  1703
      }      
deba@1697
  1704
      
deba@1697
  1705
    private:
deba@1697
  1706
      EdgeMap& edgeMap;
deba@1697
  1707
      NodeMap& nodeMap;
deba@1697
  1708
    };
deba@1697
  1709
deba@1697
  1710
  };
deba@1697
  1711
deba@1697
  1712
  template <typename _Graph>
deba@1697
  1713
  class SplitGraphAdaptor 
deba@1697
  1714
    : public IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > {
deba@1697
  1715
  public:
deba@1697
  1716
    typedef IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > Parent;
deba@1697
  1717
deba@1697
  1718
    SplitGraphAdaptor(_Graph& graph) {
deba@1697
  1719
      Parent::setGraph(graph);
deba@1697
  1720
    }
deba@1697
  1721
deba@1697
  1722
deba@1697
  1723
  };
deba@1697
  1724
alpar@921
  1725
} //namespace lemon
marci@556
  1726
alpar@1401
  1727
#endif //LEMON_GRAPH_ADAPTOR_H
marci@556
  1728