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