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