src/lemon/graph_wrapper.h
author marci
Wed, 29 Sep 2004 19:02:26 +0000
changeset 923 acbef5dd0e65
parent 921 818510fa3d99
child 930 e89f3bd26fd4
permissions -rw-r--r--
more docs
alpar@906
     1
/* -*- C++ -*-
alpar@921
     2
 * src/lemon/graph_wrapper.h - Part of LEMON, a generic C++ optimization library
alpar@906
     3
 *
alpar@906
     4
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@906
    16
alpar@921
    17
#ifndef LEMON_GRAPH_WRAPPER_H
alpar@921
    18
#define LEMON_GRAPH_WRAPPER_H
marci@556
    19
marci@556
    20
///\ingroup gwrappers
marci@556
    21
///\file
marci@556
    22
///\brief Several graph wrappers.
marci@556
    23
///
marci@556
    24
///This file contains several useful graph wrapper functions.
marci@556
    25
///
marci@556
    26
///\author Marton Makai
marci@556
    27
alpar@921
    28
#include <lemon/invalid.h>
alpar@921
    29
#include <lemon/maps.h>
alpar@921
    30
#include <lemon/map_defines.h>
alpar@774
    31
#include <iostream>
marci@556
    32
alpar@921
    33
namespace lemon {
marci@556
    34
marci@556
    35
  // Graph wrappers
marci@556
    36
marci@556
    37
  /// \addtogroup gwrappers
marci@923
    38
  /// The main parts of LEMON are the different graph structures, 
marci@556
    39
  /// generic graph algorithms, graph concepts which couple these, and 
marci@556
    40
  /// graph wrappers. While the previous ones are more or less clear, the 
marci@556
    41
  /// latter notion needs further explanation.
marci@556
    42
  /// Graph wrappers are graph classes which serve for considering graph 
marci@556
    43
  /// structures in different ways. A short example makes the notion much 
marci@556
    44
  /// clearer. 
marci@556
    45
  /// Suppose that we have an instance \c g of a directed graph
marci@556
    46
  /// type say \c ListGraph and an algorithm 
marci@556
    47
  /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
marci@556
    48
  /// is needed to run on the reversely oriented graph. 
marci@556
    49
  /// It may be expensive (in time or in memory usage) to copy 
marci@556
    50
  /// \c g with the reverse orientation. 
marci@556
    51
  /// Thus, a wrapper class
marci@556
    52
  /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@556
    53
  /// The code looks as follows
marci@556
    54
  /// \code
marci@556
    55
  /// ListGraph g;
marci@556
    56
  /// RevGraphWrapper<ListGraph> rgw(g);
marci@556
    57
  /// int result=algorithm(rgw);
marci@556
    58
  /// \endcode
marci@556
    59
  /// After running the algorithm, the original graph \c g 
marci@556
    60
  /// remains untouched. Thus the graph wrapper used above is to consider the 
marci@556
    61
  /// original graph with reverse orientation. 
marci@556
    62
  /// This techniques gives rise to an elegant code, and 
marci@556
    63
  /// based on stable graph wrappers, complex algorithms can be 
marci@556
    64
  /// implemented easily. 
marci@556
    65
  /// In flow, circulation and bipartite matching problems, the residual 
marci@556
    66
  /// graph is of particular importance. Combining a wrapper implementing 
marci@556
    67
  /// this, shortest path algorithms and minimum mean cycle algorithms, 
marci@556
    68
  /// a range of weighted and cardinality optimization algorithms can be 
marci@556
    69
  /// obtained. For lack of space, for other examples, 
marci@556
    70
  /// the interested user is referred to the detailed documentation of graph 
marci@556
    71
  /// wrappers. 
marci@556
    72
  /// The behavior of graph wrappers can be very different. Some of them keep 
marci@556
    73
  /// capabilities of the original graph while in other cases this would be 
marci@556
    74
  /// meaningless. This means that the concepts that they are a model of depend 
marci@556
    75
  /// on the graph wrapper, and the wrapped graph(s). 
marci@556
    76
  /// If an edge of \c rgw is deleted, this is carried out by 
marci@556
    77
  /// deleting the corresponding edge of \c g. But for a residual 
marci@556
    78
  /// graph, this operation has no sense. 
marci@556
    79
  /// Let we stand one more example here to simplify your work. 
marci@556
    80
  /// wrapper class
marci@556
    81
  /// \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@556
    82
  /// has constructor 
marci@556
    83
  /// <tt> RevGraphWrapper(Graph& _g)</tt>. 
marci@556
    84
  /// This means that in a situation, 
marci@556
    85
  /// when a <tt> const ListGraph& </tt> reference to a graph is given, 
marci@556
    86
  /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
marci@556
    87
  /// \code
marci@556
    88
  /// int algorithm1(const ListGraph& g) {
marci@556
    89
  ///   RevGraphWrapper<const ListGraph> rgw(g);
marci@556
    90
  ///   return algorithm2(rgw);
marci@556
    91
  /// }
marci@556
    92
  /// \endcode
marci@556
    93
marci@556
    94
  /// \addtogroup gwrappers
marci@556
    95
  /// @{
marci@556
    96
marci@556
    97
  ///Base type for the Graph Wrappers
marci@556
    98
alpar@879
    99
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
   100
  ///parts of the lib. Use them at you own risk.
alpar@879
   101
  ///
marci@923
   102
  /// This is the base type for most of LEMON graph wrappers. 
marci@923
   103
  /// This class implements a trivial graph wrapper i.e. it only wraps the 
marci@923
   104
  /// functions and types of the graph. The purpose of this class is to 
marci@923
   105
  /// make easier implementing graph wrappers. E.g. if a wrapper is 
marci@923
   106
  /// considered which differs from the wrapped graph only in some of its 
marci@923
   107
  /// functions or types, then it can be derived from GraphWrapper, and only the 
marci@923
   108
  /// differences should be implemented.
marci@556
   109
  ///
marci@612
   110
  ///\author Marton Makai 
marci@556
   111
  template<typename Graph>
marci@556
   112
  class GraphWrapper {
marci@556
   113
  protected:
marci@556
   114
    Graph* graph;
marci@556
   115
    GraphWrapper() : graph(0) { }
marci@556
   116
    void setGraph(Graph& _graph) { graph=&_graph; }
marci@556
   117
marci@556
   118
  public:
marci@556
   119
    typedef Graph BaseGraph;
marci@556
   120
    typedef Graph ParentGraph;
marci@556
   121
marci@556
   122
    GraphWrapper(Graph& _graph) : graph(&_graph) { }
alpar@774
   123
    GraphWrapper(const GraphWrapper<Graph>& gw) : graph(gw.graph) { }
marci@556
   124
 
alpar@774
   125
    typedef typename Graph::Node Node;
alpar@774
   126
    class NodeIt : public Node { 
alpar@774
   127
      const GraphWrapper<Graph>* gw;
marci@556
   128
      friend class GraphWrapper<Graph>;
marci@556
   129
     public:
marci@556
   130
      NodeIt() { }
alpar@774
   131
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   132
      NodeIt(const GraphWrapper<Graph>& _gw) : 
alpar@774
   133
	Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { }
alpar@774
   134
      NodeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   135
	Node(n), gw(&_gw) { }
alpar@774
   136
      NodeIt& operator++() { 
alpar@774
   137
	*(static_cast<Node*>(this))=
alpar@774
   138
	  ++(typename Graph::NodeIt(*(gw->graph), *this));
alpar@774
   139
	return *this; 
alpar@774
   140
      }
marci@556
   141
    };
alpar@774
   142
    typedef typename Graph::Edge Edge;
alpar@774
   143
    class OutEdgeIt : public Edge { 
alpar@774
   144
      const GraphWrapper<Graph>* gw;
marci@556
   145
      friend class GraphWrapper<Graph>;
alpar@774
   146
     public:
alpar@774
   147
      OutEdgeIt() { }
alpar@774
   148
      OutEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   149
      OutEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   150
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   151
      OutEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   152
	Edge(e), gw(&_gw) { }
alpar@774
   153
      OutEdgeIt& operator++() { 
alpar@774
   154
	*(static_cast<Edge*>(this))=
alpar@774
   155
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   156
	return *this; 
alpar@774
   157
      }
marci@556
   158
    };
alpar@774
   159
    class InEdgeIt : public Edge { 
alpar@774
   160
      const GraphWrapper<Graph>* gw;
marci@556
   161
      friend class GraphWrapper<Graph>;
alpar@774
   162
     public:
marci@556
   163
      InEdgeIt() { }
alpar@774
   164
      InEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   165
      InEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   166
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   167
      InEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   168
	Edge(e), gw(&_gw) { }
alpar@774
   169
      InEdgeIt& operator++() { 
alpar@774
   170
	*(static_cast<Edge*>(this))=
alpar@774
   171
	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   172
	return *this; 
alpar@774
   173
      }
marci@556
   174
    };
alpar@774
   175
    class EdgeIt : public Edge { 
alpar@774
   176
      const GraphWrapper<Graph>* gw;
marci@556
   177
      friend class GraphWrapper<Graph>;
alpar@774
   178
     public:
marci@556
   179
      EdgeIt() { }
alpar@774
   180
      EdgeIt(Invalid i) : Edge(i) { }
alpar@774
   181
      EdgeIt(const GraphWrapper<Graph>& _gw) : 
alpar@774
   182
	Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { }
alpar@774
   183
      EdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
marci@777
   184
	Edge(e), gw(&_gw) { }
alpar@774
   185
      EdgeIt& operator++() { 
alpar@774
   186
	*(static_cast<Edge*>(this))=
alpar@774
   187
	  ++(typename Graph::EdgeIt(*(gw->graph), *this));
alpar@774
   188
	return *this; 
alpar@774
   189
      }
marci@556
   190
    };
marci@556
   191
   
marci@556
   192
    NodeIt& first(NodeIt& i) const { 
marci@556
   193
      i=NodeIt(*this); return i;
marci@556
   194
    }
marci@556
   195
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   196
      i=OutEdgeIt(*this, p); return i;
marci@556
   197
    }
marci@556
   198
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   199
      i=InEdgeIt(*this, p); return i;
marci@556
   200
    }
marci@556
   201
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   202
      i=EdgeIt(*this); return i;
marci@556
   203
    }
marci@556
   204
marci@556
   205
    Node tail(const Edge& e) const { 
marci@556
   206
      return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
marci@556
   207
    Node head(const Edge& e) const { 
marci@556
   208
      return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
marci@556
   209
marci@556
   210
    int nodeNum() const { return graph->nodeNum(); }
marci@556
   211
    int edgeNum() const { return graph->edgeNum(); }
marci@556
   212
  
marci@556
   213
    Node addNode() const { return Node(graph->addNode()); }
marci@556
   214
    Edge addEdge(const Node& tail, const Node& head) const { 
marci@556
   215
      return Edge(graph->addEdge(tail, head)); }
marci@556
   216
marci@556
   217
    void erase(const Node& i) const { graph->erase(i); }
marci@556
   218
    void erase(const Edge& i) const { graph->erase(i); }
marci@556
   219
  
marci@556
   220
    void clear() const { graph->clear(); }
marci@556
   221
    
alpar@736
   222
    bool forward(const Edge& e) const { return graph->forward(e); }
alpar@736
   223
    bool backward(const Edge& e) const { return graph->backward(e); }
marci@739
   224
marci@739
   225
    int id(const Node& v) const { return graph->id(v); }
marci@739
   226
    int id(const Edge& e) const { return graph->id(e); }
marci@650
   227
    
marci@738
   228
    Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); }
marci@650
   229
marci@556
   230
deba@877
   231
    IMPORT_NODE_MAP(Graph, *(gw.graph), GraphWrapper, gw);    
deba@877
   232
    IMPORT_EDGE_MAP(Graph, *(gw.graph), GraphWrapper, gw);
deba@877
   233
    
deba@877
   234
marci@556
   235
  };
marci@556
   236
marci@569
   237
marci@569
   238
marci@556
   239
  /// A graph wrapper which reverses the orientation of the edges.
marci@556
   240
alpar@879
   241
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
   242
  ///parts of the lib. Use them at you own risk.
alpar@879
   243
  ///
marci@923
   244
  /// Let \f$G=(V, A)\f$ be a directed graph and 
marci@923
   245
  /// suppose that a graph instange \c g of type 
marci@923
   246
  /// \c ListGraph implements \f$G\f$.
marci@923
   247
  /// \code
marci@923
   248
  /// ListGraph g;
marci@923
   249
  /// \endcode
marci@923
   250
  /// For each directed edge 
marci@923
   251
  /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by 
marci@923
   252
  /// reversing its orientation. 
marci@923
   253
  /// Then RevGraphWrapper implements the graph structure with node-set 
marci@923
   254
  /// \f$V\f$ and edge-set 
marci@923
   255
  /// \f$\{\bar e : e\in A \}\f$, i.e. the graph obtained from \f$G\f$ be 
marci@923
   256
  /// reversing the orientation of its edges. The following code shows how 
marci@923
   257
  /// such an instance can be constructed.
marci@923
   258
  /// \code
marci@923
   259
  /// RevGraphWrapper<ListGraph> gw(g);
marci@923
   260
  /// \endcode
marci@556
   261
  ///\author Marton Makai
marci@556
   262
  template<typename Graph>
marci@556
   263
  class RevGraphWrapper : public GraphWrapper<Graph> {
marci@650
   264
  public:
marci@650
   265
    typedef GraphWrapper<Graph> Parent; 
marci@556
   266
  protected:
marci@612
   267
    RevGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   268
  public:
marci@556
   269
    RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
alpar@774
   270
    RevGraphWrapper(const RevGraphWrapper<Graph>& gw) : Parent(gw) { }
marci@556
   271
marci@556
   272
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   273
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@792
   274
    //remark: OutEdgeIt and InEdgeIt cannot be typedef-ed to each other
marci@792
   275
    //because this does not work is some of them are not defined in the 
marci@792
   276
    //original graph. The problem with this is that typedef-ed stuff 
marci@792
   277
    //are instantiated in c++.
alpar@774
   278
    class OutEdgeIt : public Edge { 
alpar@774
   279
      const RevGraphWrapper<Graph>* gw;
marci@556
   280
      friend class GraphWrapper<Graph>;
alpar@774
   281
     public:
marci@556
   282
      OutEdgeIt() { }
alpar@774
   283
      OutEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   284
      OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   285
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   286
      OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   287
	Edge(e), gw(&_gw) { }
alpar@774
   288
      OutEdgeIt& operator++() { 
alpar@774
   289
	*(static_cast<Edge*>(this))=
alpar@774
   290
	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   291
	return *this; 
alpar@774
   292
      }
marci@556
   293
    };
alpar@774
   294
    class InEdgeIt : public Edge { 
alpar@774
   295
      const RevGraphWrapper<Graph>* gw;
marci@556
   296
      friend class GraphWrapper<Graph>;
alpar@774
   297
     public:
marci@556
   298
      InEdgeIt() { }
alpar@774
   299
      InEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   300
      InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   301
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   302
      InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   303
	Edge(e), gw(&_gw) { }
alpar@774
   304
      InEdgeIt& operator++() { 
alpar@774
   305
	*(static_cast<Edge*>(this))=
alpar@774
   306
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   307
	return *this; 
alpar@774
   308
      }
marci@556
   309
    };
marci@556
   310
marci@556
   311
    using GraphWrapper<Graph>::first;
marci@556
   312
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   313
      i=OutEdgeIt(*this, p); return i;
marci@556
   314
    }
marci@556
   315
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   316
      i=InEdgeIt(*this, p); return i;
marci@556
   317
    }
marci@556
   318
marci@556
   319
    Node tail(const Edge& e) const { 
marci@556
   320
      return GraphWrapper<Graph>::head(e); }
marci@556
   321
    Node head(const Edge& e) const { 
marci@556
   322
      return GraphWrapper<Graph>::tail(e); }
marci@556
   323
deba@891
   324
    //    KEEP_MAPS(Parent, RevGraphWrapper);
deba@877
   325
marci@556
   326
  };
marci@556
   327
marci@775
   328
marci@775
   329
marci@612
   330
  /// A graph wrapper for hiding nodes and edges from a graph.
marci@556
   331
  
alpar@879
   332
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
   333
  ///parts of the lib. Use them at you own risk.
alpar@879
   334
  ///
marci@556
   335
  /// This wrapper shows a graph with filtered node-set and 
marci@923
   336
  /// edge-set. 
marci@923
   337
  /// Given a bool-valued map on the node-set and one on 
marci@923
   338
  /// the edge-set of the graph, the iterators show only the objects 
marci@923
   339
  /// having true value. We have to note that this does not mean that an 
marci@923
   340
  /// induced subgraph is obtained, the node-iterator cares only the filter 
marci@923
   341
  /// on the node-set, and the edge-iterators care only the filter on the 
marci@923
   342
  /// edge-set.
marci@923
   343
  /// \code
marci@923
   344
  /// typedef SmartGraph Graph;
marci@923
   345
  /// Graph g;
marci@923
   346
  /// typedef Graph::Node Node;
marci@923
   347
  /// typedef Graph::Edge Edge;
marci@923
   348
  /// Node u=g.addNode(); //node of id 0
marci@923
   349
  /// Node v=g.addNode(); //node of id 1
marci@923
   350
  /// Node e=g.addEdge(u, v); //edge of id 0
marci@923
   351
  /// Node f=g.addEdge(v, u); //edge of id 1
marci@923
   352
  /// Graph::NodeMap<bool> nm(g, true);
marci@923
   353
  /// nm.set(u, false);
marci@923
   354
  /// Graph::EdgeMap<bool> em(g, true);
marci@923
   355
  /// em.set(e, false);
marci@923
   356
  /// typedef SubGraphWrapper<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
marci@923
   357
  /// SubGW gw(g, nm, em);
marci@923
   358
  /// for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
marci@923
   359
  /// std::cout << ":-)" << std::endl;
marci@923
   360
  /// for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
marci@923
   361
  /// \endcode
marci@923
   362
  /// The output of the above code is the following.
marci@923
   363
  /// \code
marci@923
   364
  /// 1
marci@923
   365
  /// :-)
marci@923
   366
  /// 1
marci@923
   367
  /// \endcode
marci@923
   368
  /// Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
marci@923
   369
  /// \c Graph::Node that is why \c g.id(n) can be applied.
marci@556
   370
  ///
marci@556
   371
  ///\author Marton Makai
marci@556
   372
  template<typename Graph, typename NodeFilterMap, 
marci@556
   373
	   typename EdgeFilterMap>
marci@556
   374
  class SubGraphWrapper : public GraphWrapper<Graph> {
marci@650
   375
  public:
marci@650
   376
    typedef GraphWrapper<Graph> Parent;
marci@556
   377
  protected:
marci@556
   378
    NodeFilterMap* node_filter_map;
marci@556
   379
    EdgeFilterMap* edge_filter_map;
marci@556
   380
marci@612
   381
    SubGraphWrapper() : GraphWrapper<Graph>(), 
marci@556
   382
			node_filter_map(0), edge_filter_map(0) { }
marci@556
   383
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
marci@556
   384
      node_filter_map=&_node_filter_map;
marci@556
   385
    }
marci@556
   386
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
marci@556
   387
      edge_filter_map=&_edge_filter_map;
marci@556
   388
    }
marci@556
   389
    
marci@556
   390
  public:
marci@556
   391
    SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@556
   392
		    EdgeFilterMap& _edge_filter_map) : 
marci@556
   393
      GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
marci@556
   394
      edge_filter_map(&_edge_filter_map) { }  
marci@556
   395
marci@556
   396
    typedef typename GraphWrapper<Graph>::Node Node;
marci@775
   397
    class NodeIt : public Node { 
marci@775
   398
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   399
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@775
   400
    public:
marci@556
   401
      NodeIt() { }
marci@775
   402
      NodeIt(Invalid i) : Node(i) { }
marci@775
   403
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) : 
marci@854
   404
	Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { 
marci@854
   405
	while (*static_cast<Node*>(this)!=INVALID && 
marci@861
   406
	       !(*(gw->node_filter_map))[*this]) 
marci@854
   407
	  *(static_cast<Node*>(this))=
marci@854
   408
	    ++(typename Graph::NodeIt(*(gw->graph), *this));
marci@854
   409
      }
marci@775
   410
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   411
	     const Node& n) : 
marci@775
   412
	Node(n), gw(&_gw) { }
marci@775
   413
      NodeIt& operator++() { 
marci@775
   414
	*(static_cast<Node*>(this))=
marci@775
   415
	  ++(typename Graph::NodeIt(*(gw->graph), *this));
marci@775
   416
	while (*static_cast<Node*>(this)!=INVALID && 
marci@775
   417
	       !(*(gw->node_filter_map))[*this]) 
marci@775
   418
	  *(static_cast<Node*>(this))=
marci@775
   419
	    ++(typename Graph::NodeIt(*(gw->graph), *this));
marci@775
   420
	return *this; 
marci@556
   421
      }
marci@556
   422
    };
marci@556
   423
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@775
   424
    class OutEdgeIt : public Edge { 
marci@775
   425
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   426
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   427
    public:
marci@556
   428
      OutEdgeIt() { }
marci@775
   429
      OutEdgeIt(Invalid i) : Edge(i) { }
marci@775
   430
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) : 
marci@854
   431
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { 
marci@854
   432
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@854
   433
	       !(*(gw->edge_filter_map))[*this]) 
marci@854
   434
	  *(static_cast<Edge*>(this))=
marci@854
   435
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@854
   436
      }
marci@775
   437
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   438
	     const Edge& e) : 
marci@775
   439
	Edge(e), gw(&_gw) { }
marci@775
   440
      OutEdgeIt& operator++() { 
marci@775
   441
	*(static_cast<Edge*>(this))=
marci@775
   442
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   443
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@775
   444
	       !(*(gw->edge_filter_map))[*this]) 
marci@775
   445
	  *(static_cast<Edge*>(this))=
marci@775
   446
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   447
	return *this; 
marci@556
   448
      }
marci@556
   449
    };
marci@775
   450
    class InEdgeIt : public Edge { 
marci@775
   451
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   452
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   453
    public:
marci@556
   454
      InEdgeIt() { }
marci@775
   455
      //      InEdgeIt(const InEdgeIt& e) : Edge(e), gw(e.gw) { }
marci@775
   456
      InEdgeIt(Invalid i) : Edge(i) { }
marci@775
   457
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) : 
marci@854
   458
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { 
marci@854
   459
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@854
   460
	       !(*(gw->edge_filter_map))[*this]) 
marci@854
   461
	  *(static_cast<Edge*>(this))=
marci@854
   462
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@854
   463
      }
marci@775
   464
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   465
	     const Edge& e) : 
marci@775
   466
	Edge(e), gw(&_gw) { }
marci@775
   467
      InEdgeIt& operator++() { 
marci@775
   468
	*(static_cast<Edge*>(this))=
marci@775
   469
	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   470
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@775
   471
	       !(*(gw->edge_filter_map))[*this]) 
marci@775
   472
	  *(static_cast<Edge*>(this))=
marci@775
   473
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   474
	return *this; 
marci@556
   475
      }
marci@556
   476
    };
marci@775
   477
    class EdgeIt : public Edge { 
marci@775
   478
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   479
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   480
    public:
marci@556
   481
      EdgeIt() { }
marci@775
   482
      EdgeIt(Invalid i) : Edge(i) { }
marci@775
   483
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) : 
marci@854
   484
	Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { 
marci@854
   485
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@854
   486
	       !(*(gw->edge_filter_map))[*this]) 
marci@854
   487
	  *(static_cast<Edge*>(this))=
marci@854
   488
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@854
   489
      }
marci@775
   490
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   491
	     const Edge& e) : 
marci@775
   492
	Edge(e), gw(&_gw) { }
marci@775
   493
      EdgeIt& operator++() { 
marci@775
   494
	*(static_cast<Edge*>(this))=
marci@775
   495
	  ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   496
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@775
   497
	       !(*(gw->edge_filter_map))[*this]) 
marci@775
   498
	  *(static_cast<Edge*>(this))=
marci@775
   499
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   500
	return *this; 
marci@556
   501
      }
marci@556
   502
    };
marci@556
   503
marci@556
   504
    NodeIt& first(NodeIt& i) const { 
marci@556
   505
      i=NodeIt(*this); return i;
marci@556
   506
    }
marci@556
   507
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   508
      i=OutEdgeIt(*this, p); return i;
marci@556
   509
    }
marci@556
   510
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   511
      i=InEdgeIt(*this, p); return i;
marci@556
   512
    }
marci@556
   513
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   514
      i=EdgeIt(*this); return i;
marci@556
   515
    }
marci@556
   516
    
marci@561
   517
    /// This function hides \c n in the graph, i.e. the iteration 
marci@561
   518
    /// jumps over it. This is done by simply setting the value of \c n  
marci@561
   519
    /// to be false in the corresponding node-map.
marci@556
   520
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@561
   521
marci@561
   522
    /// This function hides \c e in the graph, i.e. the iteration 
marci@561
   523
    /// jumps over it. This is done by simply setting the value of \c e  
marci@561
   524
    /// to be false in the corresponding edge-map.
marci@556
   525
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@556
   526
marci@561
   527
    /// The value of \c n is set to be true in the node-map which stores 
marci@561
   528
    /// hide information. If \c n was hidden previuosly, then it is shown 
marci@561
   529
    /// again
marci@561
   530
     void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@561
   531
marci@561
   532
    /// The value of \c e is set to be true in the edge-map which stores 
marci@561
   533
    /// hide information. If \c e was hidden previuosly, then it is shown 
marci@561
   534
    /// again
marci@556
   535
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@556
   536
marci@561
   537
    /// Returns true if \c n is hidden.
marci@561
   538
    bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
marci@561
   539
marci@561
   540
    /// Returns true if \c n is hidden.
marci@561
   541
    bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
marci@593
   542
marci@792
   543
    /// \warning This is a linear time operation and works only if 
marci@792
   544
    /// \c Graph::NodeIt is defined.
marci@593
   545
    int nodeNum() const { 
marci@593
   546
      int i=0;
marci@792
   547
      for (NodeIt n(*this); n!=INVALID; ++n) ++i;
marci@593
   548
      return i; 
marci@593
   549
    }
marci@593
   550
marci@792
   551
    /// \warning This is a linear time operation and works only if 
marci@792
   552
    /// \c Graph::EdgeIt is defined.
marci@593
   553
    int edgeNum() const { 
marci@593
   554
      int i=0;
marci@792
   555
      for (EdgeIt e(*this); e!=INVALID; ++e) ++i;
marci@593
   556
      return i; 
marci@593
   557
    }
marci@593
   558
deba@891
   559
    //    KEEP_MAPS(Parent, SubGraphWrapper);
marci@556
   560
  };
marci@556
   561
marci@569
   562
marci@569
   563
marci@556
   564
  template<typename Graph>
marci@556
   565
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@650
   566
  public:
marci@650
   567
    typedef GraphWrapper<Graph> Parent; 
marci@556
   568
  protected:
marci@556
   569
    UndirGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   570
    
marci@556
   571
  public:
marci@556
   572
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   573
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   574
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   575
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@556
   576
marci@556
   577
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@556
   578
marci@556
   579
    class OutEdgeIt {
marci@556
   580
      friend class UndirGraphWrapper<Graph>;
marci@556
   581
      bool out_or_in; //true iff out
marci@556
   582
      typename Graph::OutEdgeIt out;
marci@556
   583
      typename Graph::InEdgeIt in;
marci@556
   584
    public:
marci@556
   585
      OutEdgeIt() { }
marci@556
   586
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@556
   587
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@556
   588
	out_or_in=true; _G.graph->first(out, _n);
marci@556
   589
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@556
   590
      } 
marci@556
   591
      operator Edge() const { 
marci@556
   592
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@556
   593
      }
marci@556
   594
    };
marci@556
   595
marci@556
   596
    typedef OutEdgeIt InEdgeIt; 
marci@556
   597
marci@556
   598
    using GraphWrapper<Graph>::first;
marci@556
   599
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   600
      i=OutEdgeIt(*this, p); return i;
marci@556
   601
    }
marci@556
   602
marci@556
   603
    using GraphWrapper<Graph>::next;
alpar@878
   604
marci@556
   605
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@556
   606
      if (e.out_or_in) {
marci@556
   607
	typename Graph::Node n=this->graph->tail(e.out);
marci@556
   608
	this->graph->next(e.out);
marci@556
   609
	if (!this->graph->valid(e.out)) { 
marci@556
   610
	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@556
   611
      } else {
marci@556
   612
	this->graph->next(e.in);
marci@556
   613
      }
marci@556
   614
      return e;
marci@556
   615
    }
marci@556
   616
marci@556
   617
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   618
      if (e.out_or_in) return this->graph->tail(e); else 
marci@556
   619
	return this->graph->head(e); }
marci@556
   620
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   621
      if (e.out_or_in) return this->graph->head(e); else 
marci@556
   622
	return this->graph->tail(e); }
deba@877
   623
deba@891
   624
    //    KEEP_MAPS(Parent, UndirGraphWrapper);
deba@877
   625
marci@556
   626
  };
marci@556
   627
  
marci@910
   628
//   /// \brief An undirected graph template.
marci@910
   629
//   ///
marci@910
   630
//   ///\warning Graph wrappers are in even more experimental state than the other
marci@910
   631
//   ///parts of the lib. Use them at your own risk.
marci@910
   632
//   ///
marci@910
   633
//   /// An undirected graph template.
marci@910
   634
//   /// This class works as an undirected graph and a directed graph of 
marci@910
   635
//   /// class \c Graph is used for the physical storage.
marci@910
   636
//   /// \ingroup graphs
marci@556
   637
  template<typename Graph>
marci@556
   638
  class UndirGraph : public UndirGraphWrapper<Graph> {
marci@556
   639
    typedef UndirGraphWrapper<Graph> Parent;
marci@556
   640
  protected:
marci@556
   641
    Graph gr;
marci@556
   642
  public:
marci@556
   643
    UndirGraph() : UndirGraphWrapper<Graph>() { 
marci@556
   644
      Parent::setGraph(gr); 
marci@556
   645
    }
deba@877
   646
deba@891
   647
    //    KEEP_MAPS(Parent, UndirGraph);
marci@556
   648
  };
marci@556
   649
marci@569
   650
marci@650
   651
marci@650
   652
  ///\brief A wrapper for composing a subgraph of a 
marci@792
   653
  /// bidirected graph made from a directed one. 
marci@612
   654
  ///
alpar@911
   655
  /// A wrapper for composing a subgraph of a 
alpar@911
   656
  /// bidirected graph made from a directed one. 
alpar@911
   657
  ///
alpar@879
   658
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
   659
  ///parts of the lib. Use them at you own risk.
alpar@879
   660
  ///
marci@923
   661
  /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge 
marci@923
   662
  /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
marci@923
   663
  /// reversing its orientation. We are given moreover two bool valued 
marci@923
   664
  /// maps on the edge-set, 
marci@923
   665
  /// \f$forward\_filter\f$, and \f$backward\_filter\f$. 
marci@923
   666
  /// SubBidirGraphWrapper implements the graph structure with node-set 
marci@923
   667
  /// \f$V\f$ and edge-set 
marci@923
   668
  /// \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$. 
marci@792
   669
  /// The purpose of writing + instead of union is because parallel 
marci@923
   670
  /// edges can arise. (Similarly, antiparallel edges also can arise).
marci@792
   671
  /// In other words, a subgraph of the bidirected graph obtained, which 
marci@792
   672
  /// is given by orienting the edges of the original graph in both directions.
marci@923
   673
  /// As the oppositely directed edges are logically different, 
marci@923
   674
  /// the maps are able to attach different values for them. 
marci@923
   675
  ///
marci@923
   676
  /// An example for such a construction is \c RevGraphWrapper where the 
marci@792
   677
  /// forward_filter is everywhere false and the backward_filter is 
marci@792
   678
  /// everywhere true. We note that for sake of efficiency, 
marci@792
   679
  /// \c RevGraphWrapper is implemented in a different way. 
marci@792
   680
  /// But BidirGraphWrapper is obtained from 
marci@792
   681
  /// SubBidirGraphWrapper by considering everywhere true 
marci@910
   682
  /// valued maps both for forward_filter and backward_filter. 
marci@792
   683
  /// Finally, one of the most important applications of SubBidirGraphWrapper 
marci@792
   684
  /// is ResGraphWrapper, which stands for the residual graph in directed 
marci@792
   685
  /// flow and circulation problems. 
marci@792
   686
  /// As wrappers usually, the SubBidirGraphWrapper implements the 
marci@792
   687
  /// above mentioned graph structure without its physical storage, 
marci@923
   688
  /// that is the whole stuff is stored in constant memory. 
marci@650
   689
  template<typename Graph, 
marci@650
   690
	   typename ForwardFilterMap, typename BackwardFilterMap>
marci@650
   691
  class SubBidirGraphWrapper : public GraphWrapper<Graph> {
marci@650
   692
  public:
marci@650
   693
    typedef GraphWrapper<Graph> Parent; 
marci@569
   694
  protected:
marci@650
   695
    ForwardFilterMap* forward_filter;
marci@650
   696
    BackwardFilterMap* backward_filter;
marci@650
   697
marci@792
   698
    SubBidirGraphWrapper() : GraphWrapper<Graph>() { }
marci@650
   699
    void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
marci@650
   700
      forward_filter=&_forward_filter;
marci@650
   701
    }
marci@650
   702
    void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
marci@650
   703
      backward_filter=&_backward_filter;
marci@650
   704
    }
marci@569
   705
marci@569
   706
  public:
marci@569
   707
marci@650
   708
    SubBidirGraphWrapper(Graph& _graph, ForwardFilterMap& _forward_filter, 
marci@650
   709
			 BackwardFilterMap& _backward_filter) : 
marci@650
   710
      GraphWrapper<Graph>(_graph), 
marci@650
   711
      forward_filter(&_forward_filter), backward_filter(&_backward_filter) { }
alpar@774
   712
    SubBidirGraphWrapper(const SubBidirGraphWrapper<Graph, 
alpar@774
   713
			 ForwardFilterMap, BackwardFilterMap>& gw) : 
alpar@774
   714
      Parent(gw), 
alpar@774
   715
      forward_filter(gw.forward_filter), 
alpar@774
   716
      backward_filter(gw.backward_filter) { }
marci@569
   717
marci@569
   718
    class Edge; 
marci@569
   719
    class OutEdgeIt; 
marci@569
   720
    friend class Edge; 
marci@569
   721
    friend class OutEdgeIt; 
marci@569
   722
marci@621
   723
    template<typename T> class EdgeMap;
marci@621
   724
marci@569
   725
    typedef typename GraphWrapper<Graph>::Node Node;
marci@621
   726
alpar@774
   727
    typedef typename Graph::Edge GraphEdge;
marci@792
   728
    /// SubBidirGraphWrapper<..., ..., ...>::Edge is inherited from 
marci@910
   729
    /// Graph::Edge. It contains an extra bool flag which is true 
marci@910
   730
    /// if and only if the 
marci@792
   731
    /// edge is the backward version of the original edge.
marci@569
   732
    class Edge : public Graph::Edge {
marci@650
   733
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   734
					ForwardFilterMap, BackwardFilterMap>;
marci@621
   735
      template<typename T> friend class EdgeMap;
marci@569
   736
    protected:
marci@569
   737
      bool backward; //true, iff backward
marci@569
   738
    public:
marci@569
   739
      Edge() { }
marci@792
   740
      /// \todo =false is needed, or causes problems?
marci@792
   741
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@792
   742
      /// original one, otherwise its oppositely directed pair is obtained.
alpar@774
   743
      Edge(const typename Graph::Edge& e, bool _backward/*=false*/) : 
alpar@774
   744
	Graph::Edge(e), backward(_backward) { }
alpar@774
   745
      Edge(Invalid i) : Graph::Edge(i), backward(true) { }
alpar@774
   746
      bool operator==(const Edge& v) const { 
alpar@774
   747
	return (this->backward==v.backward && 
alpar@774
   748
		static_cast<typename Graph::Edge>(*this)==
marci@569
   749
		static_cast<typename Graph::Edge>(v));
marci@569
   750
      } 
alpar@774
   751
      bool operator!=(const Edge& v) const { 
alpar@774
   752
	return (this->backward!=v.backward || 
alpar@774
   753
		static_cast<typename Graph::Edge>(*this)!=
marci@569
   754
		static_cast<typename Graph::Edge>(v));
alpar@774
   755
      }
marci@569
   756
    };
marci@569
   757
alpar@774
   758
    class OutEdgeIt : public Edge {
marci@650
   759
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   760
					ForwardFilterMap, BackwardFilterMap>;
marci@569
   761
    protected:
alpar@774
   762
      const SubBidirGraphWrapper<Graph, 
alpar@774
   763
				 ForwardFilterMap, BackwardFilterMap>* gw;
marci@569
   764
    public:
marci@569
   765
      OutEdgeIt() { }
alpar@774
   766
      OutEdgeIt(Invalid i) : Edge(i) { }
marci@650
   767
      OutEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   768
		ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) : 
alpar@774
   769
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), false), gw(&_gw) { 
alpar@774
   770
	while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   771
	       !(*(gw->forward_filter))[*this]) 
alpar@774
   772
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   773
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   774
	if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   775
	  *static_cast<Edge*>(this)=
alpar@774
   776
	    Edge(typename Graph::InEdgeIt(*(_gw.graph), n), true);
marci@775
   777
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   778
		 !(*(gw->backward_filter))[*this]) 
marci@775
   779
	    *(static_cast<GraphEdge*>(this))=
marci@775
   780
	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   781
	}
alpar@774
   782
      }
alpar@774
   783
      OutEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   784
		ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
alpar@774
   785
	Edge(e), gw(&_gw) { }
alpar@774
   786
      OutEdgeIt& operator++() { 
alpar@774
   787
	if (!this->backward) {
alpar@774
   788
	  Node n=gw->tail(*this);
alpar@774
   789
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   790
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   791
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   792
		 !(*(gw->forward_filter))[*this]) 
alpar@774
   793
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   794
	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   795
	  if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   796
	    *static_cast<Edge*>(this)=
alpar@774
   797
	      Edge(typename Graph::InEdgeIt(*(gw->graph), n), true);
marci@775
   798
	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   799
		   !(*(gw->backward_filter))[*this]) 
marci@775
   800
	      *(static_cast<GraphEdge*>(this))=
marci@775
   801
		++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   802
	  }
alpar@774
   803
	} else {
alpar@774
   804
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   805
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   806
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   807
		 !(*(gw->backward_filter))[*this]) 
alpar@774
   808
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   809
	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@569
   810
	}
alpar@774
   811
	return *this;
marci@569
   812
      }
marci@569
   813
    };
marci@569
   814
alpar@774
   815
    class InEdgeIt : public Edge {
marci@650
   816
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   817
					ForwardFilterMap, BackwardFilterMap>;
marci@569
   818
    protected:
alpar@774
   819
      const SubBidirGraphWrapper<Graph, 
alpar@774
   820
				 ForwardFilterMap, BackwardFilterMap>* gw;
marci@569
   821
    public:
marci@569
   822
      InEdgeIt() { }
alpar@774
   823
      InEdgeIt(Invalid i) : Edge(i) { }
marci@650
   824
      InEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   825
	       ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) : 
alpar@774
   826
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n), false), gw(&_gw) { 
alpar@774
   827
	while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   828
	       !(*(gw->forward_filter))[*this]) 
alpar@774
   829
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   830
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   831
	if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   832
	  *static_cast<Edge*>(this)=
alpar@774
   833
	    Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), true);
marci@775
   834
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   835
		 !(*(gw->backward_filter))[*this]) 
marci@775
   836
	    *(static_cast<GraphEdge*>(this))=
marci@775
   837
	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   838
	}
alpar@774
   839
      }
alpar@774
   840
      InEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   841
	       ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
alpar@774
   842
	Edge(e), gw(&_gw) { }
alpar@774
   843
      InEdgeIt& operator++() { 
alpar@774
   844
	if (!this->backward) {
marci@775
   845
	  Node n=gw->tail(*this);
alpar@774
   846
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   847
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   848
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   849
		 !(*(gw->forward_filter))[*this]) 
alpar@774
   850
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   851
	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   852
	  if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   853
	    *static_cast<Edge*>(this)=
alpar@774
   854
	      Edge(typename Graph::OutEdgeIt(*(gw->graph), n), true);
marci@775
   855
	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   856
		   !(*(gw->backward_filter))[*this]) 
marci@775
   857
	      *(static_cast<GraphEdge*>(this))=
marci@775
   858
		++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   859
	  }
alpar@774
   860
	} else {
alpar@774
   861
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   862
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   863
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   864
		 !(*(gw->backward_filter))[*this]) 
alpar@774
   865
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   866
	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@569
   867
	}
alpar@774
   868
	return *this;
marci@569
   869
      }
marci@569
   870
    };
marci@569
   871
alpar@774
   872
    class EdgeIt : public Edge {
marci@650
   873
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   874
					ForwardFilterMap, BackwardFilterMap>;
marci@569
   875
    protected:
alpar@774
   876
      const SubBidirGraphWrapper<Graph, 
alpar@774
   877
				 ForwardFilterMap, BackwardFilterMap>* gw;
marci@569
   878
    public:
marci@569
   879
      EdgeIt() { }
alpar@774
   880
      EdgeIt(Invalid i) : Edge(i) { }
marci@650
   881
      EdgeIt(const SubBidirGraphWrapper<Graph, 
marci@775
   882
	     ForwardFilterMap, BackwardFilterMap>& _gw) : 
marci@892
   883
	Edge(typename Graph::EdgeIt(*(_gw.graph)), false), gw(&_gw) { 
alpar@774
   884
	while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   885
	       !(*(gw->forward_filter))[*this]) 
alpar@774
   886
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   887
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   888
	if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   889
	  *static_cast<Edge*>(this)=
alpar@774
   890
	    Edge(typename Graph::EdgeIt(*(_gw.graph)), true);
marci@775
   891
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   892
		 !(*(gw->backward_filter))[*this]) 
marci@775
   893
	    *(static_cast<GraphEdge*>(this))=
marci@775
   894
	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   895
	}
alpar@774
   896
      }
alpar@774
   897
      EdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   898
	     ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
alpar@774
   899
	Edge(e), gw(&_gw) { }
alpar@774
   900
      EdgeIt& operator++() { 
alpar@774
   901
	if (!this->backward) {
alpar@774
   902
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   903
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
alpar@774
   904
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   905
		 !(*(gw->forward_filter))[*this]) 
alpar@774
   906
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   907
	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   908
	  if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   909
	    *static_cast<Edge*>(this)=
alpar@774
   910
	      Edge(typename Graph::EdgeIt(*(gw->graph)), true);
marci@775
   911
	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   912
		   !(*(gw->backward_filter))[*this]) 
marci@775
   913
	      *(static_cast<GraphEdge*>(this))=
marci@775
   914
		++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   915
	  }
alpar@774
   916
	} else {
alpar@774
   917
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   918
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
alpar@774
   919
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   920
		 !(*(gw->backward_filter))[*this]) 
alpar@774
   921
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   922
	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@569
   923
	}
alpar@774
   924
	return *this;
marci@569
   925
      }
marci@569
   926
    };
marci@569
   927
marci@569
   928
    using GraphWrapper<Graph>::first;
marci@569
   929
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@569
   930
      i=OutEdgeIt(*this, p); return i;
marci@569
   931
    }
marci@569
   932
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@569
   933
      i=InEdgeIt(*this, p); return i;
marci@569
   934
    }
marci@569
   935
    EdgeIt& first(EdgeIt& i) const { 
marci@569
   936
      i=EdgeIt(*this); return i;
marci@569
   937
    }
marci@556
   938
  
marci@569
   939
marci@569
   940
    Node tail(Edge e) const { 
marci@569
   941
      return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@569
   942
    Node head(Edge e) const { 
marci@569
   943
      return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@569
   944
marci@572
   945
    /// Gives back the opposite edge.
marci@572
   946
    Edge opposite(const Edge& e) const { 
marci@572
   947
      Edge f=e;
marci@572
   948
      f.backward=!f.backward;
marci@572
   949
      return f;
marci@572
   950
    }
marci@572
   951
marci@792
   952
    /// \warning This is a linear time operation and works only if 
marci@792
   953
    /// \c Graph::EdgeIt is defined.
marci@792
   954
    int edgeNum() const { 
marci@792
   955
      int i=0;
marci@792
   956
      for (EdgeIt e(*this); e!=INVALID; ++e) ++i;
marci@792
   957
      return i; 
marci@792
   958
    }
marci@569
   959
marci@569
   960
    bool forward(const Edge& e) const { return !e.backward; }
marci@569
   961
    bool backward(const Edge& e) const { return e.backward; }
marci@569
   962
marci@569
   963
marci@569
   964
    template <typename T>
marci@792
   965
    /// \c SubBidirGraphWrapper<..., ..., ...>::EdgeMap contains two 
marci@792
   966
    /// Graph::EdgeMap one for the forward edges and 
marci@792
   967
    /// one for the backward edges.
marci@569
   968
    class EdgeMap {
deba@891
   969
      template <typename TT> friend class EdgeMap;
marci@569
   970
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@569
   971
    public:
marci@623
   972
      typedef T ValueType;
marci@623
   973
      typedef Edge KeyType;
deba@891
   974
marci@650
   975
      EdgeMap(const SubBidirGraphWrapper<Graph, 
alpar@774
   976
	      ForwardFilterMap, BackwardFilterMap>& g) : 
alpar@774
   977
	forward_map(*(g.graph)), backward_map(*(g.graph)) { }
deba@891
   978
marci@650
   979
      EdgeMap(const SubBidirGraphWrapper<Graph, 
alpar@774
   980
	      ForwardFilterMap, BackwardFilterMap>& g, T a) : 
alpar@774
   981
	forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
deba@891
   982
deba@891
   983
      template <typename TT>
deba@891
   984
      EdgeMap(const EdgeMap<TT>& copy) 
deba@891
   985
	: forward_map(copy.forward_map), backward_map(copy.backward_map) {}
deba@891
   986
deba@891
   987
      template <typename TT>
deba@891
   988
      EdgeMap& operator=(const EdgeMap<TT>& copy) {
deba@891
   989
	forward_map = copy.forward_map;
deba@891
   990
	backward_map = copy.backward_map;
deba@891
   991
	return *this;
deba@891
   992
      }
deba@891
   993
      
marci@569
   994
      void set(Edge e, T a) { 
marci@569
   995
	if (!e.backward) 
marci@792
   996
	  forward_map.set(e, a); 
marci@569
   997
	else 
marci@792
   998
	  backward_map.set(e, a); 
marci@569
   999
      }
deba@891
  1000
deba@891
  1001
      typename Graph::template EdgeMap<T>::ConstReferenceType 
deba@891
  1002
      operator[](Edge e) const { 
marci@569
  1003
	if (!e.backward) 
marci@792
  1004
	  return forward_map[e]; 
marci@569
  1005
	else 
marci@792
  1006
	  return backward_map[e]; 
marci@569
  1007
      }
deba@891
  1008
deba@891
  1009
      typename Graph::template EdgeMap<T>::ReferenceType 
deba@891
  1010
      operator[](Edge e) { 
deba@891
  1011
	if (!e.backward) 
deba@891
  1012
	  return forward_map[e]; 
deba@891
  1013
	else 
deba@891
  1014
	  return backward_map[e]; 
deba@891
  1015
      }
deba@891
  1016
marci@625
  1017
      void update() { 
marci@625
  1018
	forward_map.update(); 
marci@625
  1019
	backward_map.update();
marci@625
  1020
      }
marci@569
  1021
    };
deba@877
  1022
deba@877
  1023
deba@891
  1024
    //    KEEP_NODE_MAP(Parent, SubBidirGraphWrapper);
deba@877
  1025
marci@569
  1026
  };
marci@569
  1027
marci@650
  1028
marci@650
  1029
  ///\brief A wrapper for composing bidirected graph from a directed one. 
marci@650
  1030
  ///
alpar@879
  1031
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1032
  ///parts of the lib. Use them at you own risk.
alpar@879
  1033
  ///
marci@650
  1034
  /// A wrapper for composing bidirected graph from a directed one. 
marci@650
  1035
  /// A bidirected graph is composed over the directed one without physical 
marci@650
  1036
  /// storage. As the oppositely directed edges are logically different ones 
marci@650
  1037
  /// the maps are able to attach different values for them.
marci@650
  1038
  template<typename Graph>
marci@650
  1039
  class BidirGraphWrapper : 
marci@650
  1040
    public SubBidirGraphWrapper<
marci@650
  1041
    Graph, 
marci@650
  1042
    ConstMap<typename Graph::Edge, bool>, 
marci@650
  1043
    ConstMap<typename Graph::Edge, bool> > {
marci@650
  1044
  public:
marci@650
  1045
    typedef  SubBidirGraphWrapper<
marci@650
  1046
      Graph, 
marci@650
  1047
      ConstMap<typename Graph::Edge, bool>, 
marci@650
  1048
      ConstMap<typename Graph::Edge, bool> > Parent; 
marci@650
  1049
  protected:
marci@650
  1050
    ConstMap<typename Graph::Edge, bool> cm;
marci@650
  1051
marci@655
  1052
    BidirGraphWrapper() : Parent(), cm(true) { 
marci@655
  1053
      Parent::setForwardFilterMap(cm);
marci@655
  1054
      Parent::setBackwardFilterMap(cm);
marci@655
  1055
    }
marci@650
  1056
  public:
marci@650
  1057
    BidirGraphWrapper(Graph& _graph) : Parent() { 
marci@650
  1058
      Parent::setGraph(_graph);
marci@650
  1059
      Parent::setForwardFilterMap(cm);
marci@650
  1060
      Parent::setBackwardFilterMap(cm);
marci@650
  1061
    }
marci@738
  1062
marci@738
  1063
    int edgeNum() const { 
marci@738
  1064
      return 2*this->graph->edgeNum();
marci@738
  1065
    }
deba@891
  1066
    //    KEEP_MAPS(Parent, BidirGraphWrapper);
marci@650
  1067
  };
marci@650
  1068
marci@650
  1069
marci@612
  1070
  /// \brief A bidirected graph template.
marci@612
  1071
  ///
alpar@879
  1072
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1073
  ///parts of the lib. Use them at you own risk.
alpar@879
  1074
  ///
marci@612
  1075
  /// A bidirected graph template.
marci@612
  1076
  /// Such a bidirected graph stores each pair of oppositely directed edges 
marci@612
  1077
  /// ones in the memory, i.e. a directed graph of type 
marci@612
  1078
  /// \c Graph is used for that.
marci@612
  1079
  /// As the oppositely directed edges are logically different ones 
marci@612
  1080
  /// the maps are able to attach different values for them.
marci@612
  1081
  /// \ingroup graphs
marci@612
  1082
  template<typename Graph>
marci@612
  1083
  class BidirGraph : public BidirGraphWrapper<Graph> {
marci@650
  1084
  public:
marci@612
  1085
    typedef UndirGraphWrapper<Graph> Parent;
marci@612
  1086
  protected:
marci@612
  1087
    Graph gr;
marci@612
  1088
  public:
marci@612
  1089
    BidirGraph() : BidirGraphWrapper<Graph>() { 
marci@612
  1090
      Parent::setGraph(gr); 
marci@612
  1091
    }
deba@891
  1092
    //    KEEP_MAPS(Parent, BidirGraph);
marci@612
  1093
  };
marci@569
  1094
marci@556
  1095
marci@650
  1096
marci@650
  1097
  template<typename Graph, typename Number,
marci@650
  1098
	   typename CapacityMap, typename FlowMap>
marci@658
  1099
  class ResForwardFilter {
marci@658
  1100
    //    const Graph* graph;
marci@650
  1101
    const CapacityMap* capacity;
marci@650
  1102
    const FlowMap* flow;
marci@650
  1103
  public:
marci@658
  1104
    ResForwardFilter(/*const Graph& _graph, */
marci@658
  1105
		     const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1106
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1107
    ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@656
  1108
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1109
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1110
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1111
      return (Number((*flow)[e]) < Number((*capacity)[e]));
marci@650
  1112
    }
marci@650
  1113
  };
marci@650
  1114
marci@650
  1115
  template<typename Graph, typename Number,
marci@650
  1116
	   typename CapacityMap, typename FlowMap>
marci@658
  1117
  class ResBackwardFilter {
marci@650
  1118
    const CapacityMap* capacity;
marci@650
  1119
    const FlowMap* flow;
marci@650
  1120
  public:
marci@658
  1121
    ResBackwardFilter(/*const Graph& _graph,*/ 
marci@658
  1122
		      const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1123
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1124
    ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@656
  1125
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1126
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1127
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1128
      return (Number(0) < Number((*flow)[e]));
marci@650
  1129
    }
marci@650
  1130
  };
marci@650
  1131
marci@653
  1132
  
marci@653
  1133
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@650
  1134
alpar@879
  1135
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1136
  ///parts of the lib. Use them at you own risk.
alpar@879
  1137
  ///
marci@653
  1138
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@650
  1139
  template<typename Graph, typename Number, 
marci@650
  1140
	   typename CapacityMap, typename FlowMap>
marci@653
  1141
  class ResGraphWrapper : 
marci@650
  1142
    public SubBidirGraphWrapper< 
marci@650
  1143
    Graph, 
marci@658
  1144
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1145
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
marci@650
  1146
  public:
marci@650
  1147
    typedef SubBidirGraphWrapper< 
marci@650
  1148
      Graph, 
marci@658
  1149
      ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1150
      ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
marci@650
  1151
  protected:
marci@650
  1152
    const CapacityMap* capacity;
marci@650
  1153
    FlowMap* flow;
marci@658
  1154
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
marci@658
  1155
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
marci@658
  1156
    ResGraphWrapper() : Parent(), 
marci@658
  1157
 			capacity(0), flow(0) { }
marci@658
  1158
    void setCapacityMap(const CapacityMap& _capacity) {
marci@658
  1159
      capacity=&_capacity;
marci@658
  1160
      forward_filter.setCapacity(_capacity);
marci@658
  1161
      backward_filter.setCapacity(_capacity);
marci@658
  1162
    }
marci@658
  1163
    void setFlowMap(FlowMap& _flow) {
marci@658
  1164
      flow=&_flow;
marci@658
  1165
      forward_filter.setFlow(_flow);
marci@658
  1166
      backward_filter.setFlow(_flow);
marci@658
  1167
    }
marci@650
  1168
  public:
marci@653
  1169
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@650
  1170
		       FlowMap& _flow) : 
marci@650
  1171
      Parent(), capacity(&_capacity), flow(&_flow), 
marci@658
  1172
      forward_filter(/*_graph,*/ _capacity, _flow), 
marci@658
  1173
      backward_filter(/*_graph,*/ _capacity, _flow) {
marci@650
  1174
      Parent::setGraph(_graph);
marci@650
  1175
      Parent::setForwardFilterMap(forward_filter);
marci@650
  1176
      Parent::setBackwardFilterMap(backward_filter);
marci@650
  1177
    }
marci@650
  1178
marci@660
  1179
    typedef typename Parent::Edge Edge;
marci@660
  1180
marci@660
  1181
    void augment(const Edge& e, Number a) const {
marci@650
  1182
      if (Parent::forward(e))  
marci@650
  1183
	flow->set(e, (*flow)[e]+a);
marci@650
  1184
      else  
marci@650
  1185
	flow->set(e, (*flow)[e]-a);
marci@650
  1186
    }
marci@650
  1187
marci@660
  1188
    /// \brief Residual capacity map.
marci@660
  1189
    ///
marci@910
  1190
    /// In generic residual graphs the residual capacity can be obtained 
marci@910
  1191
    /// as a map. 
marci@660
  1192
    class ResCap {
marci@660
  1193
    protected:
marci@660
  1194
      const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>* res_graph;
marci@660
  1195
    public:
marci@660
  1196
      typedef Number ValueType;
marci@660
  1197
      typedef Edge KeyType;
marci@888
  1198
      ResCap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& 
marci@888
  1199
	     _res_graph) : res_graph(&_res_graph) { }
marci@660
  1200
      Number operator[](const Edge& e) const { 
marci@660
  1201
	if (res_graph->forward(e)) 
marci@660
  1202
	  return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; 
marci@660
  1203
	else 
marci@660
  1204
	  return (*(res_graph->flow))[e]; 
marci@660
  1205
      }
marci@660
  1206
    };
marci@660
  1207
deba@891
  1208
    //    KEEP_MAPS(Parent, ResGraphWrapper);
marci@650
  1209
  };
marci@650
  1210
marci@650
  1211
marci@612
  1212
  /// For blocking flows.
marci@556
  1213
alpar@879
  1214
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1215
  ///parts of the lib. Use them at you own risk.
alpar@879
  1216
  ///
marci@792
  1217
  /// This graph wrapper is used for on-the-fly 
marci@792
  1218
  /// Dinits blocking flow computations.
marci@612
  1219
  /// For each node, an out-edge is stored which is used when the 
marci@612
  1220
  /// \code 
marci@612
  1221
  /// OutEdgeIt& first(OutEdgeIt&, const Node&)
marci@612
  1222
  /// \endcode
marci@612
  1223
  /// is called. 
marci@556
  1224
  ///
marci@792
  1225
  /// \author Marton Makai
marci@556
  1226
  template<typename Graph, typename FirstOutEdgesMap>
marci@556
  1227
  class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@650
  1228
  public:
marci@650
  1229
    typedef GraphWrapper<Graph> Parent; 
marci@556
  1230
  protected:
marci@556
  1231
    FirstOutEdgesMap* first_out_edges;
marci@556
  1232
  public:
marci@556
  1233
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@556
  1234
			     FirstOutEdgesMap& _first_out_edges) : 
marci@556
  1235
      GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@556
  1236
marci@556
  1237
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
  1238
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@777
  1239
    class OutEdgeIt : public Edge { 
marci@556
  1240
      friend class GraphWrapper<Graph>;
marci@556
  1241
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@777
  1242
      const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>* gw;
marci@556
  1243
    public:
marci@556
  1244
      OutEdgeIt() { }
marci@777
  1245
      OutEdgeIt(Invalid i) : Edge(i) { }
marci@777
  1246
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw, 
marci@777
  1247
		const Node& n) : 
marci@777
  1248
	Edge((*(_gw.first_out_edges))[n]), gw(&_gw) { }
marci@777
  1249
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw, 
marci@777
  1250
		const Edge& e) : 
marci@777
  1251
	Edge(e), gw(&_gw) { }
marci@777
  1252
      OutEdgeIt& operator++() { 
marci@777
  1253
	*(static_cast<Edge*>(this))=
marci@777
  1254
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@777
  1255
	return *this; 
marci@777
  1256
      }
marci@556
  1257
    };
marci@556
  1258
marci@556
  1259
    using GraphWrapper<Graph>::first;
marci@556
  1260
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
  1261
      i=OutEdgeIt(*this, p); return i;
marci@556
  1262
    }
marci@777
  1263
    void erase(const Edge& e) const {
marci@777
  1264
      Node n=tail(e);
deba@844
  1265
      typename Graph::OutEdgeIt f(*Parent::graph, n);
marci@777
  1266
      ++f;
marci@777
  1267
      first_out_edges->set(n, f);
marci@556
  1268
    }
deba@877
  1269
deba@891
  1270
    //    KEEP_MAPS(Parent, ErasingFirstGraphWrapper);
marci@556
  1271
  };
marci@556
  1272
marci@556
  1273
  ///@}
marci@556
  1274
alpar@921
  1275
} //namespace lemon
marci@556
  1276
alpar@921
  1277
#endif //LEMON_GRAPH_WRAPPER_H
marci@556
  1278