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