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