src/work/marci/graph_wrapper.h
author marci
Fri, 30 Apr 2004 17:10:01 +0000
changeset 499 767f3da8ce0e
parent 497 500456d50d21
child 524 bd8109f8e2fa
permissions -rw-r--r--
A bipartite graph template can be used as BipartiteGraph<ListGraph>.
marci@174
     1
// -*- c++ -*-
marci@259
     2
#ifndef HUGO_GRAPH_WRAPPER_H
marci@259
     3
#define HUGO_GRAPH_WRAPPER_H
marci@76
     4
klao@491
     5
///\ingroup gwrappers
alpar@457
     6
///\file
alpar@457
     7
///\brief Several graph wrappers.
alpar@457
     8
///
alpar@457
     9
///This file contains several useful graph wrapper functions.
alpar@457
    10
///
alpar@457
    11
///\author Marton Makai
alpar@457
    12
marci@174
    13
#include <invalid.h>
marci@499
    14
//#include <iter_map.h>
marci@174
    15
alpar@105
    16
namespace hugo {
marci@76
    17
alpar@438
    18
  // Graph wrappers
alpar@438
    19
alpar@406
    20
  /// \addtogroup gwrappers
alpar@344
    21
  /// A main parts of HUGOlib are the different graph structures, 
marci@335
    22
  /// generic graph algorithms, graph concepts which couple these, and 
marci@335
    23
  /// graph wrappers. While the previous ones are more or less clear, the 
marci@335
    24
  /// latter notion needs further explanation.
marci@335
    25
  /// Graph wrappers are graph classes which serve for considering graph 
alpar@344
    26
  /// structures in different ways. A short example makes the notion much 
alpar@344
    27
  /// clearer. 
alpar@344
    28
  /// Suppose that we have an instance \c g of a directed graph
alpar@344
    29
  /// type say \c ListGraph and an algorithm 
marci@335
    30
  /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
alpar@344
    31
  /// is needed to run on the reversely oriented graph. 
alpar@344
    32
  /// It may be expensive (in time or in memory usage) to copy 
alpar@344
    33
  /// \c g with the reverse orientation. 
marci@335
    34
  /// Thus, a wrapper class
marci@335
    35
  /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@335
    36
  /// The code looks as follows
marci@335
    37
  /// \code
marci@335
    38
  /// ListGraph g;
marci@335
    39
  /// RevGraphWrapper<ListGraph> rgw(g);
marci@335
    40
  /// int result=algorithm(rgw);
marci@335
    41
  /// \endcode
alpar@344
    42
  /// After running the algorithm, the original graph \c g 
alpar@344
    43
  /// remains untouched. Thus the graph wrapper used above is to consider the 
alpar@344
    44
  /// original graph with reverse orientation. 
marci@335
    45
  /// This techniques gives rise to an elegant code, and 
marci@335
    46
  /// based on stable graph wrappers, complex algorithms can be 
marci@335
    47
  /// implemented easily. 
marci@335
    48
  /// In flow, circulation and bipartite matching problems, the residual 
alpar@344
    49
  /// graph is of particular importance. Combining a wrapper implementing 
alpar@344
    50
  /// this, shortest path algorithms and minimum mean cycle algorithms, 
marci@335
    51
  /// a range of weighted and cardinality optimization algorithms can be 
marci@335
    52
  /// obtained. For lack of space, for other examples, 
alpar@344
    53
  /// the interested user is referred to the detailed documentation of graph 
marci@335
    54
  /// wrappers. 
alpar@344
    55
  /// The behavior of graph wrappers can be very different. Some of them keep 
marci@335
    56
  /// capabilities of the original graph while in other cases this would be 
alpar@344
    57
  /// meaningless. This means that the concepts that they are a model of depend 
marci@335
    58
  /// on the graph wrapper, and the wrapped graph(s). 
alpar@344
    59
  /// If an edge of \c rgw is deleted, this is carried out by 
alpar@344
    60
  /// deleting the corresponding edge of \c g. But for a residual 
marci@335
    61
  /// graph, this operation has no sense. 
marci@335
    62
  /// Let we stand one more example here to simplify your work. 
marci@335
    63
  /// wrapper class
marci@335
    64
  /// \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@335
    65
  /// has constructor 
alpar@344
    66
  /// <tt> RevGraphWrapper(Graph& _g)</tt>. 
marci@335
    67
  /// This means that in a situation, 
alpar@344
    68
  /// when a <tt> const ListGraph& </tt> reference to a graph is given, 
alpar@344
    69
  /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
marci@335
    70
  /// \code
marci@335
    71
  /// int algorithm1(const ListGraph& g) {
marci@335
    72
  ///   RevGraphWrapper<const ListGraph> rgw(g);
marci@335
    73
  ///   return algorithm2(rgw);
marci@335
    74
  /// }
marci@335
    75
  /// \endcode
alpar@438
    76
alpar@438
    77
  /// \addtogroup gwrappers
alpar@438
    78
  /// @{
alpar@438
    79
alpar@438
    80
  ///Base type for the Graph Wrappers
alpar@438
    81
alpar@438
    82
  ///This is the base type for the Graph Wrappers.
alpar@457
    83
  ///\todo Some more docs... 
alpar@457
    84
  ///
alpar@457
    85
  ///\author Marton Makai
alpar@457
    86
 
marci@303
    87
  template<typename Graph>
marci@303
    88
  class GraphWrapper {
marci@212
    89
  protected:
marci@303
    90
    Graph* graph;
marci@497
    91
    GraphWrapper() : graph(0) { }
marci@497
    92
    void setGraph(Graph& _graph) { graph=&_graph; }
marci@497
    93
marci@212
    94
  public:
marci@311
    95
    typedef Graph BaseGraph;
marci@303
    96
    typedef Graph ParentGraph;
marci@212
    97
marci@303
    98
    GraphWrapper(Graph& _graph) : graph(&_graph) { }
marci@303
    99
//     Graph& getGraph() const { return *graph; }
marci@303
   100
 
marci@317
   101
//    typedef typename Graph::Node Node;
marci@317
   102
    class Node : public Graph::Node {
marci@317
   103
      friend class GraphWrapper<Graph>;
marci@265
   104
    public:
marci@317
   105
      Node() { }
marci@317
   106
      Node(const typename Graph::Node& _n) : Graph::Node(_n) { }
marci@317
   107
      Node(const Invalid& i) : Graph::Node(i) { }
marci@317
   108
    };
marci@317
   109
    class NodeIt { 
marci@317
   110
      friend class GraphWrapper<Graph>;
marci@317
   111
      typename Graph::NodeIt n;
marci@317
   112
     public:
marci@265
   113
      NodeIt() { }
marci@317
   114
      NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@317
   115
      NodeIt(const Invalid& i) : n(i) { }
marci@317
   116
      NodeIt(const GraphWrapper<Graph>& _G) : n(*(_G.graph)) { }
marci@317
   117
      operator Node() const { return Node(typename Graph::Node(n)); }
marci@265
   118
    };
marci@317
   119
//    typedef typename Graph::Edge Edge;
marci@317
   120
    class Edge : public Graph::Edge {
marci@317
   121
      friend class GraphWrapper<Graph>;
marci@317
   122
    public:
marci@317
   123
      Edge() { }
marci@317
   124
      Edge(const typename Graph::Edge& _e) : Graph::Edge(_e) { }
marci@317
   125
      Edge(const Invalid& i) : Graph::Edge(i) { }
marci@317
   126
    };
marci@317
   127
    class OutEdgeIt { 
marci@317
   128
      friend class GraphWrapper<Graph>;
marci@317
   129
      typename Graph::OutEdgeIt e;
marci@265
   130
    public:
marci@265
   131
      OutEdgeIt() { }
marci@317
   132
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317
   133
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@317
   134
      OutEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@317
   135
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317
   136
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265
   137
    };
marci@317
   138
    class InEdgeIt { 
marci@317
   139
      friend class GraphWrapper<Graph>;
marci@317
   140
      typename Graph::InEdgeIt e;
marci@265
   141
    public:
marci@265
   142
      InEdgeIt() { }
marci@317
   143
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317
   144
      InEdgeIt(const Invalid& i) : e(i) { }
marci@317
   145
      InEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@317
   146
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317
   147
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265
   148
    };
marci@303
   149
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317
   150
    class EdgeIt { 
marci@317
   151
      friend class GraphWrapper<Graph>;
marci@317
   152
      typename Graph::EdgeIt e;
marci@265
   153
    public:
marci@265
   154
      EdgeIt() { }
marci@317
   155
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317
   156
      EdgeIt(const Invalid& i) : e(i) { }
marci@317
   157
      EdgeIt(const GraphWrapper<Graph>& _G) : e(*(_G.graph)) { }
marci@317
   158
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265
   159
    };
marci@303
   160
   
marci@303
   161
    NodeIt& first(NodeIt& i) const { 
marci@317
   162
      i=NodeIt(*this); return i;
marci@265
   163
    }
marci@303
   164
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   165
      i=OutEdgeIt(*this, p); return i;
marci@303
   166
    }
marci@303
   167
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   168
      i=InEdgeIt(*this, p); return i;
marci@303
   169
    }
marci@311
   170
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   171
      i=EdgeIt(*this); return i;
marci@311
   172
    }
marci@338
   173
marci@317
   174
    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@317
   175
    OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
marci@317
   176
    InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
marci@317
   177
    EdgeIt& next(EdgeIt& i) const { graph->next(i.e); return i; }    
marci@212
   178
marci@379
   179
    Node tail(const Edge& e) const { 
marci@379
   180
      return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
marci@317
   181
    Node head(const Edge& e) const { 
marci@317
   182
      return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
marci@212
   183
marci@317
   184
    bool valid(const Node& n) const { 
marci@317
   185
      return graph->valid(static_cast<typename Graph::Node>(n)); }
marci@317
   186
    bool valid(const Edge& e) const { 
marci@317
   187
      return graph->valid(static_cast<typename Graph::Edge>(e)); }
marci@212
   188
marci@303
   189
    int nodeNum() const { return graph->nodeNum(); }
marci@303
   190
    int edgeNum() const { return graph->edgeNum(); }
marci@212
   191
  
marci@317
   192
    Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317
   193
    Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317
   194
    Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@317
   195
    Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@212
   196
  
marci@317
   197
    Node addNode() const { return Node(graph->addNode()); }
marci@212
   198
    Edge addEdge(const Node& tail, const Node& head) const { 
marci@317
   199
      return Edge(graph->addEdge(tail, head)); }
marci@317
   200
marci@317
   201
    void erase(const Node& i) const { graph->erase(i); }
marci@317
   202
    void erase(const Edge& i) const { graph->erase(i); }
marci@212
   203
  
marci@303
   204
    void clear() const { graph->clear(); }
marci@212
   205
    
marci@389
   206
    template<typename T> class NodeMap : public Graph::template NodeMap<T> { 
marci@389
   207
      typedef typename Graph::template NodeMap<T> Parent;
marci@212
   208
    public:
marci@389
   209
      NodeMap(const GraphWrapper<Graph>& _G) :  Parent(*(_G.graph)) { }
marci@389
   210
      NodeMap(const GraphWrapper<Graph>& _G, T a) : Parent(*(_G.graph), a) { }
marci@212
   211
    };
marci@212
   212
marci@389
   213
    template<typename T> class EdgeMap : public Graph::template EdgeMap<T> { 
marci@389
   214
      typedef typename Graph::template EdgeMap<T> Parent;
marci@212
   215
    public:
marci@389
   216
      EdgeMap(const GraphWrapper<Graph>& _G) : Parent(*(_G.graph)) { }
marci@389
   217
      EdgeMap(const GraphWrapper<Graph>& _G, T a) : Parent(*(_G.graph), a) { }
marci@212
   218
    };
marci@212
   219
  };
marci@212
   220
marci@338
   221
  /// A graph wrapper which reverses the orientation of the edges.
marci@303
   222
marci@338
   223
  /// A graph wrapper which reverses the orientation of the edges.
alpar@457
   224
  ///
alpar@457
   225
  ///\author Marton Makai
marci@303
   226
  template<typename Graph>
marci@303
   227
  class RevGraphWrapper : public GraphWrapper<Graph> {
marci@497
   228
  protected:
marci@497
   229
    RevGraphWrapper() : GraphWrapper<Graph>(0) { }
marci@230
   230
  public:
marci@338
   231
    RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@338
   232
marci@303
   233
    typedef typename GraphWrapper<Graph>::Node Node;
marci@303
   234
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@303
   235
    //If Graph::OutEdgeIt is not defined
marci@279
   236
    //and we do not want to use RevGraphWrapper::InEdgeIt,
marci@338
   237
    //the typdef techinque does not work.
marci@338
   238
    //Unfortunately all the typedefs are instantiated in templates.
marci@338
   239
    //typedef typename GraphWrapper<Graph>::OutEdgeIt InEdgeIt;
marci@338
   240
    //typedef typename GraphWrapper<Graph>::InEdgeIt OutEdgeIt;
marci@237
   241
marci@338
   242
    class OutEdgeIt { 
marci@338
   243
      friend class GraphWrapper<Graph>;
marci@338
   244
      friend class RevGraphWrapper<Graph>;
marci@379
   245
      typename Graph::InEdgeIt e;
marci@338
   246
    public:
marci@338
   247
      OutEdgeIt() { }
marci@379
   248
      OutEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@338
   249
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@338
   250
      OutEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@338
   251
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@338
   252
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@338
   253
    };
marci@338
   254
    class InEdgeIt { 
marci@338
   255
      friend class GraphWrapper<Graph>;
marci@338
   256
      friend class RevGraphWrapper<Graph>;
marci@379
   257
      typename Graph::OutEdgeIt e;
marci@338
   258
    public:
marci@338
   259
      InEdgeIt() { }
marci@379
   260
      InEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@338
   261
      InEdgeIt(const Invalid& i) : e(i) { }
marci@338
   262
      InEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@338
   263
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@338
   264
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@338
   265
    };
marci@238
   266
marci@338
   267
    using GraphWrapper<Graph>::first;
marci@338
   268
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@338
   269
      i=OutEdgeIt(*this, p); return i;
marci@338
   270
    }
marci@338
   271
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@338
   272
      i=InEdgeIt(*this, p); return i;
marci@338
   273
    }
marci@338
   274
marci@338
   275
    using GraphWrapper<Graph>::next;
marci@389
   276
    OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389
   277
    InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@338
   278
marci@389
   279
    Node aNode(const OutEdgeIt& e) const { 
marci@389
   280
      return Node(this->graph->aNode(e.e)); }
marci@389
   281
    Node aNode(const InEdgeIt& e) const { 
marci@389
   282
      return Node(this->graph->aNode(e.e)); }
marci@389
   283
    Node bNode(const OutEdgeIt& e) const { 
marci@389
   284
      return Node(this->graph->bNode(e.e)); }
marci@389
   285
    Node bNode(const InEdgeIt& e) const { 
marci@389
   286
      return Node(this->graph->bNode(e.e)); }
marci@379
   287
marci@379
   288
    Node tail(const Edge& e) const { 
marci@379
   289
      return GraphWrapper<Graph>::head(e); }
marci@379
   290
    Node head(const Edge& e) const { 
marci@379
   291
      return GraphWrapper<Graph>::tail(e); }
marci@379
   292
marci@76
   293
  };
marci@76
   294
marci@335
   295
  /// Wrapper for hiding nodes and edges from a graph.
marci@335
   296
  
marci@335
   297
  /// This wrapper shows a graph with filtered node-set and 
klao@363
   298
  /// edge-set. The quick brown fox iterator jumps over 
marci@335
   299
  /// the lazy dog nodes or edges if the values for them are false 
marci@335
   300
  /// in the bool maps. 
alpar@457
   301
  ///
alpar@457
   302
  ///\author Marton Makai
marci@311
   303
  template<typename Graph, typename NodeFilterMap, 
marci@311
   304
	   typename EdgeFilterMap>
marci@303
   305
  class SubGraphWrapper : public GraphWrapper<Graph> {
marci@263
   306
  protected:
marci@311
   307
    NodeFilterMap* node_filter_map;
marci@311
   308
    EdgeFilterMap* edge_filter_map;
marci@497
   309
marci@497
   310
    SubGraphWrapper() : GraphWrapper<Graph>(0), 
marci@497
   311
			node_filter_map(0), edge_filter_map(0) { }
marci@497
   312
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
marci@497
   313
      node_filter_map=&_node_filte_map;
marci@497
   314
    }
marci@497
   315
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
marci@497
   316
      edge_filter_map=&_edge_filte_map;
marci@497
   317
    }
marci@497
   318
    
marci@263
   319
  public:
marci@338
   320
marci@311
   321
    SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@311
   322
		    EdgeFilterMap& _edge_filter_map) : 
marci@311
   323
      GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
marci@311
   324
      edge_filter_map(&_edge_filter_map) { }  
marci@263
   325
marci@317
   326
    typedef typename GraphWrapper<Graph>::Node Node;
marci@317
   327
    class NodeIt { 
marci@317
   328
      friend class GraphWrapper<Graph>;
marci@317
   329
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   330
      typename Graph::NodeIt n;
marci@317
   331
     public:
marci@311
   332
      NodeIt() { }
marci@317
   333
      NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@317
   334
      NodeIt(const Invalid& i) : n(i) { }
marci@311
   335
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@317
   336
	n(*(_G.graph)) { 
marci@317
   337
	while (_G.graph->valid(n) && !(*(_G.node_filter_map))[n]) 
marci@317
   338
	  _G.graph->next(n);
marci@311
   339
      }
marci@317
   340
      operator Node() const { return Node(typename Graph::Node(n)); }
marci@311
   341
    };
marci@317
   342
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317
   343
    class OutEdgeIt { 
marci@317
   344
      friend class GraphWrapper<Graph>;
marci@317
   345
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   346
      typename Graph::OutEdgeIt e;
marci@311
   347
    public:
marci@311
   348
      OutEdgeIt() { }
marci@317
   349
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317
   350
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@317
   351
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@317
   352
		const Node& _n) : 
marci@317
   353
	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@317
   354
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317
   355
	  _G.graph->next(e);
marci@311
   356
      }
marci@317
   357
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   358
    };
marci@317
   359
    class InEdgeIt { 
marci@317
   360
      friend class GraphWrapper<Graph>;
marci@317
   361
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   362
      typename Graph::InEdgeIt e;
marci@311
   363
    public:
marci@311
   364
      InEdgeIt() { }
marci@317
   365
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317
   366
      InEdgeIt(const Invalid& i) : e(i) { }
marci@311
   367
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@317
   368
	       const Node& _n) : 
marci@317
   369
	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@317
   370
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317
   371
	  _G.graph->next(e);
marci@311
   372
      }
marci@317
   373
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   374
    };
marci@317
   375
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317
   376
    class EdgeIt { 
marci@317
   377
      friend class GraphWrapper<Graph>;
marci@317
   378
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   379
      typename Graph::EdgeIt e;
marci@311
   380
    public:
marci@311
   381
      EdgeIt() { }
marci@317
   382
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317
   383
      EdgeIt(const Invalid& i) : e(i) { }
marci@311
   384
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@317
   385
	e(*(_G.graph)) { 
marci@317
   386
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317
   387
	  _G.graph->next(e);
marci@311
   388
      }
marci@317
   389
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   390
    };
marci@317
   391
marci@317
   392
    NodeIt& first(NodeIt& i) const { 
marci@317
   393
      i=NodeIt(*this); return i;
marci@263
   394
    }
marci@317
   395
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   396
      i=OutEdgeIt(*this, p); return i;
marci@311
   397
    }
marci@317
   398
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   399
      i=InEdgeIt(*this, p); return i;
marci@311
   400
    }
marci@317
   401
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   402
      i=EdgeIt(*this); return i;
marci@263
   403
    }
marci@263
   404
    
marci@311
   405
    NodeIt& next(NodeIt& i) const {
marci@389
   406
      this->graph->next(i.n); 
marci@389
   407
      while (this->graph->valid(i) && !(*node_filter_map)[i.n]) { 
marci@389
   408
	this->graph->next(i.n); }
marci@311
   409
      return i;
marci@311
   410
    }
marci@311
   411
    OutEdgeIt& next(OutEdgeIt& i) const {
marci@389
   412
      this->graph->next(i.e); 
marci@389
   413
      while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@389
   414
	this->graph->next(i.e); }
marci@311
   415
      return i;
marci@311
   416
    }
marci@311
   417
    InEdgeIt& next(InEdgeIt& i) const {
marci@389
   418
      this->graph->next(i.e); 
marci@389
   419
      while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@389
   420
	this->graph->next(i.e); }
marci@311
   421
      return i;
marci@311
   422
    }
marci@311
   423
    EdgeIt& next(EdgeIt& i) const {
marci@389
   424
      this->graph->next(i.e); 
marci@389
   425
      while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@389
   426
	this->graph->next(i.e); }
marci@311
   427
      return i;
marci@311
   428
    }
marci@311
   429
marci@389
   430
    Node aNode(const OutEdgeIt& e) const { 
marci@389
   431
      return Node(this->graph->aNode(e.e)); }
marci@389
   432
    Node aNode(const InEdgeIt& e) const { 
marci@389
   433
      return Node(this->graph->aNode(e.e)); }
marci@389
   434
    Node bNode(const OutEdgeIt& e) const { 
marci@389
   435
      return Node(this->graph->bNode(e.e)); }
marci@389
   436
    Node bNode(const InEdgeIt& e) const { 
marci@389
   437
      return Node(this->graph->bNode(e.e)); }
marci@323
   438
alpar@357
   439
    ///\todo
alpar@357
   440
    ///Some doki, please.
marci@323
   441
    void hide(const Node& n) const { node_filter_map->set(n, false); }
alpar@357
   442
    ///\todo
alpar@357
   443
    ///Some doki, please.
marci@323
   444
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@323
   445
alpar@357
   446
    ///\todo
alpar@357
   447
    ///Some doki, please.
marci@323
   448
    void unHide(const Node& n) const { node_filter_map->set(n, true); }
alpar@357
   449
    ///\todo
alpar@357
   450
    ///Some doki, please.
marci@323
   451
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@323
   452
alpar@357
   453
    ///\todo
alpar@357
   454
    ///Some doki, please.
marci@323
   455
    bool hidden(const Node& n) const { return (*node_filter_map)[n]; }
alpar@357
   456
    ///\todo
alpar@357
   457
    ///Some doki, please.
marci@323
   458
    bool hidden(const Edge& e) const { return (*edge_filter_map)[e]; }
marci@263
   459
  };
marci@155
   460
alpar@356
   461
  /// A wrapper for forgetting the orientation of a graph.
marci@317
   462
alpar@356
   463
  /// A wrapper for getting an undirected graph by forgetting
alpar@356
   464
  /// the orientation of a directed one.
marci@303
   465
  template<typename Graph>
marci@303
   466
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@497
   467
  protected:
marci@497
   468
    UndirGraphWrapper() : GraphWrapper<Graph>(0) { }
marci@497
   469
    
marci@303
   470
  public:
marci@303
   471
    typedef typename GraphWrapper<Graph>::Node Node;
marci@303
   472
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@317
   473
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317
   474
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@236
   475
marci@303
   476
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@158
   477
marci@317
   478
    class OutEdgeIt {
marci@303
   479
      friend class UndirGraphWrapper<Graph>;
marci@158
   480
      bool out_or_in; //true iff out
marci@317
   481
      typename Graph::OutEdgeIt out;
marci@317
   482
      typename Graph::InEdgeIt in;
marci@158
   483
    public:
marci@317
   484
      OutEdgeIt() { }
marci@317
   485
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@317
   486
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@317
   487
	out_or_in=true; _G.graph->first(out, _n);
marci@317
   488
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@174
   489
      } 
marci@317
   490
      operator Edge() const { 
marci@317
   491
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@158
   492
      }
marci@158
   493
    };
marci@158
   494
marci@317
   495
//FIXME InEdgeIt
marci@238
   496
    typedef OutEdgeIt InEdgeIt; 
marci@238
   497
marci@338
   498
    using GraphWrapper<Graph>::first;
marci@338
   499
//     NodeIt& first(NodeIt& i) const { 
marci@338
   500
//       i=NodeIt(*this); return i;
marci@338
   501
//     }
marci@317
   502
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   503
      i=OutEdgeIt(*this, p); return i;
marci@317
   504
    }
marci@317
   505
//FIXME
marci@317
   506
//     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   507
//       i=InEdgeIt(*this, p); return i;
marci@317
   508
//     }
marci@338
   509
//     EdgeIt& first(EdgeIt& i) const { 
marci@338
   510
//       i=EdgeIt(*this); return i;
marci@338
   511
//     }
marci@238
   512
marci@338
   513
    using GraphWrapper<Graph>::next;
marci@338
   514
//     NodeIt& next(NodeIt& n) const {
marci@338
   515
//       GraphWrapper<Graph>::next(n);
marci@338
   516
//       return n;
marci@338
   517
//     }
marci@158
   518
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@158
   519
      if (e.out_or_in) {
marci@389
   520
	typename Graph::Node n=this->graph->tail(e.out);
marci@389
   521
	this->graph->next(e.out);
marci@389
   522
	if (!this->graph->valid(e.out)) { 
marci@389
   523
	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@158
   524
      } else {
marci@389
   525
	this->graph->next(e.in);
marci@158
   526
      }
marci@158
   527
      return e;
marci@158
   528
    }
marci@317
   529
    //FIXME InEdgeIt
marci@338
   530
//     EdgeIt& next(EdgeIt& e) const {
marci@338
   531
//       GraphWrapper<Graph>::next(n);
marci@338
   532
// //      graph->next(e.e);
marci@338
   533
//       return e;
marci@338
   534
//     }
marci@238
   535
marci@238
   536
    Node aNode(const OutEdgeIt& e) const { 
marci@389
   537
      if (e.out_or_in) return this->graph->tail(e); else 
marci@389
   538
	return this->graph->head(e); }
marci@238
   539
    Node bNode(const OutEdgeIt& e) const { 
marci@389
   540
      if (e.out_or_in) return this->graph->head(e); else 
marci@389
   541
	return this->graph->tail(e); }
marci@338
   542
  };
marci@158
   543
  
marci@338
   544
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@238
   545
marci@338
   546
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@330
   547
  template<typename Graph, typename Number, 
marci@330
   548
	   typename CapacityMap, typename FlowMap>
marci@311
   549
  class ResGraphWrapper : public GraphWrapper<Graph> {
marci@199
   550
  protected:
marci@330
   551
    const CapacityMap* capacity;
marci@155
   552
    FlowMap* flow;
marci@497
   553
marci@497
   554
    ResGraphWrapper() : GraphWrapper<Graph>(0), 
marci@497
   555
			capacity(0), flow(0) { }
marci@497
   556
    void setCapacityMap(const CapacityMap& _capacity_map) {
marci@497
   557
      capacity_map=&_capacity_map;
marci@497
   558
    }
marci@497
   559
    void setFlowMap(FlowMap& _flow) {
marci@497
   560
      flow=&_flow;
marci@497
   561
    }
marci@497
   562
marci@155
   563
  public:
marci@168
   564
marci@330
   565
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@330
   566
		    FlowMap& _flow) : 
marci@330
   567
      GraphWrapper<Graph>(_graph), capacity(&_capacity), flow(&_flow) { }
marci@168
   568
marci@174
   569
    class Edge; 
marci@155
   570
    class OutEdgeIt; 
marci@174
   571
    friend class Edge; 
marci@155
   572
    friend class OutEdgeIt; 
marci@76
   573
marci@311
   574
    typedef typename GraphWrapper<Graph>::Node Node;
marci@311
   575
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@317
   576
    class Edge : public Graph::Edge {
marci@330
   577
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@155
   578
    protected:
marci@317
   579
      bool forward; //true, iff forward
marci@317
   580
//      typename Graph::Edge e;
marci@155
   581
    public:
marci@317
   582
      Edge() { }
marci@317
   583
      Edge(const typename Graph::Edge& _e, bool _forward) : 
marci@317
   584
	Graph::Edge(_e), forward(_forward) { }
marci@317
   585
      Edge(const Invalid& i) : Graph::Edge(i), forward(false) { }
marci@317
   586
//the unique invalid iterator
marci@174
   587
      friend bool operator==(const Edge& u, const Edge& v) { 
marci@317
   588
	return (v.forward==u.forward && 
marci@317
   589
		static_cast<typename Graph::Edge>(u)==
marci@317
   590
		static_cast<typename Graph::Edge>(v));
marci@174
   591
      } 
marci@174
   592
      friend bool operator!=(const Edge& u, const Edge& v) { 
marci@317
   593
	return (v.forward!=u.forward || 
marci@317
   594
		static_cast<typename Graph::Edge>(u)!=
marci@317
   595
		static_cast<typename Graph::Edge>(v));
marci@174
   596
      } 
marci@155
   597
    };
marci@338
   598
marci@317
   599
    class OutEdgeIt {
marci@330
   600
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317
   601
    protected:
marci@317
   602
      typename Graph::OutEdgeIt out;
marci@317
   603
      typename Graph::InEdgeIt in;
marci@317
   604
      bool forward;
marci@155
   605
    public:
marci@155
   606
      OutEdgeIt() { }
marci@168
   607
      //FIXME
marci@317
   608
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@317
   609
      OutEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@317
   610
//the unique invalid iterator
marci@330
   611
      OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@317
   612
	forward=true;
marci@303
   613
	resG.graph->first(out, v);
marci@317
   614
	while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@303
   615
	if (!resG.graph->valid(out)) {
marci@317
   616
	  forward=false;
marci@303
   617
	  resG.graph->first(in, v);
marci@317
   618
	  while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@155
   619
	}
marci@155
   620
      }
marci@317
   621
      operator Edge() const { 
marci@317
   622
//	Edge e;
marci@317
   623
//	e.forward=this->forward;
marci@317
   624
//	if (this->forward) e=out; else e=in;
marci@317
   625
//	return e;
marci@317
   626
	if (this->forward) 
marci@317
   627
	  return Edge(out, this->forward); 
marci@317
   628
	else 
marci@317
   629
	  return Edge(in, this->forward);
marci@317
   630
      }
marci@317
   631
    };
marci@263
   632
marci@317
   633
    class InEdgeIt {
marci@330
   634
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317
   635
    protected:
marci@317
   636
      typename Graph::OutEdgeIt out;
marci@317
   637
      typename Graph::InEdgeIt in;
marci@317
   638
      bool forward;
marci@317
   639
    public:
marci@317
   640
      InEdgeIt() { }
marci@317
   641
      //FIXME
marci@317
   642
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@317
   643
      InEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@317
   644
//the unique invalid iterator
marci@330
   645
      InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@317
   646
	forward=true;
marci@317
   647
	resG.graph->first(in, v);
marci@317
   648
	while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@317
   649
	if (!resG.graph->valid(in)) {
marci@317
   650
	  forward=false;
marci@317
   651
	  resG.graph->first(out, v);
marci@317
   652
	  while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@317
   653
	}
marci@317
   654
      }
marci@317
   655
      operator Edge() const { 
marci@317
   656
//	Edge e;
marci@317
   657
//	e.forward=this->forward;
marci@317
   658
//	if (this->forward) e=out; else e=in;
marci@317
   659
//	return e;
marci@317
   660
	if (this->forward) 
marci@317
   661
	  return Edge(in, this->forward); 
marci@317
   662
	else 
marci@317
   663
	  return Edge(out, this->forward);
marci@317
   664
      }
marci@317
   665
    };
marci@317
   666
marci@317
   667
    class EdgeIt {
marci@330
   668
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317
   669
    protected:
marci@317
   670
      typename Graph::EdgeIt e;
marci@317
   671
      bool forward;
marci@155
   672
    public:
marci@174
   673
      EdgeIt() { }
marci@317
   674
      EdgeIt(const Invalid& i) : e(i), forward(false) { }
marci@330
   675
      EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG) { 
marci@317
   676
	forward=true;
marci@317
   677
	resG.graph->first(e);
marci@317
   678
	while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@317
   679
	if (!resG.graph->valid(e)) {
marci@317
   680
	  forward=false;
marci@317
   681
	  resG.graph->first(e);
marci@317
   682
	  while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@155
   683
	}
marci@155
   684
      }
marci@317
   685
      operator Edge() const { 
marci@317
   686
	return Edge(e, this->forward);
marci@317
   687
      }
marci@317
   688
    };
marci@155
   689
marci@338
   690
    using GraphWrapper<Graph>::first;
marci@338
   691
//     NodeIt& first(NodeIt& i) const { 
marci@338
   692
//       i=NodeIt(*this); return i;
marci@338
   693
//     }
marci@311
   694
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   695
      i=OutEdgeIt(*this, p); return i;
marci@311
   696
    }
marci@317
   697
//    FIXME not tested
marci@317
   698
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   699
      i=InEdgeIt(*this, p); return i;
marci@317
   700
    }
marci@317
   701
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   702
      i=EdgeIt(*this); return i;
marci@155
   703
    }
marci@338
   704
  
marci@338
   705
    using GraphWrapper<Graph>::next;
marci@338
   706
//    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@155
   707
    OutEdgeIt& next(OutEdgeIt& e) const { 
marci@317
   708
      if (e.forward) {
marci@389
   709
	Node v=this->graph->aNode(e.out);
marci@389
   710
	this->graph->next(e.out);
marci@389
   711
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@389
   712
	  this->graph->next(e.out); }
marci@389
   713
	if (!this->graph->valid(e.out)) {
marci@317
   714
	  e.forward=false;
marci@389
   715
	  this->graph->first(e.in, v); 
marci@389
   716
	  while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@389
   717
	    this->graph->next(e.in); }
marci@155
   718
	}
marci@155
   719
      } else {
marci@389
   720
	this->graph->next(e.in);
marci@389
   721
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@389
   722
	  this->graph->next(e.in); } 
marci@155
   723
      }
marci@155
   724
      return e;
marci@155
   725
    }
marci@317
   726
//     FIXME Not tested
marci@317
   727
    InEdgeIt& next(InEdgeIt& e) const { 
marci@317
   728
      if (e.forward) {
marci@389
   729
	Node v=this->graph->aNode(e.in);
marci@389
   730
	this->graph->next(e.in);
marci@389
   731
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@389
   732
	  this->graph->next(e.in); }
marci@389
   733
	if (!this->graph->valid(e.in)) {
marci@317
   734
	  e.forward=false;
marci@389
   735
	  this->graph->first(e.out, v); 
marci@389
   736
	  while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@389
   737
	    this->graph->next(e.out); }
marci@317
   738
	}
marci@317
   739
      } else {
marci@389
   740
	this->graph->next(e.out);
marci@389
   741
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@389
   742
	  this->graph->next(e.out); } 
marci@317
   743
      }
marci@317
   744
      return e;
marci@317
   745
    }
marci@317
   746
    EdgeIt& next(EdgeIt& e) const {
marci@317
   747
      if (e.forward) {
marci@389
   748
	this->graph->next(e.e);
marci@389
   749
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@389
   750
	  this->graph->next(e.e); }
marci@389
   751
	if (!this->graph->valid(e.e)) {
marci@317
   752
	  e.forward=false;
marci@389
   753
	  this->graph->first(e.e); 
marci@389
   754
	  while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@389
   755
	    this->graph->next(e.e); }
marci@155
   756
	}
marci@317
   757
      } else {
marci@389
   758
	this->graph->next(e.e);
marci@389
   759
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@389
   760
	  this->graph->next(e.e); } 
marci@155
   761
      }
marci@317
   762
      return e;
marci@317
   763
    }
marci@76
   764
marci@174
   765
    Node tail(Edge e) const { 
marci@389
   766
      return ((e.forward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@174
   767
    Node head(Edge e) const { 
marci@389
   768
      return ((e.forward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@76
   769
marci@174
   770
    Node aNode(OutEdgeIt e) const { 
marci@389
   771
      return ((e.forward) ? this->graph->aNode(e.out) : 
marci@389
   772
	      this->graph->aNode(e.in)); }
marci@174
   773
    Node bNode(OutEdgeIt e) const { 
marci@389
   774
      return ((e.forward) ? this->graph->bNode(e.out) : 
marci@389
   775
	      this->graph->bNode(e.in)); }
marci@76
   776
marci@376
   777
    Node aNode(InEdgeIt e) const { 
marci@389
   778
      return ((e.forward) ? this->graph->aNode(e.in) : 
marci@389
   779
	      this->graph->aNode(e.out)); }
marci@376
   780
    Node bNode(InEdgeIt e) const { 
marci@389
   781
      return ((e.forward) ? this->graph->bNode(e.in) : 
marci@389
   782
	      this->graph->bNode(e.out)); }
marci@376
   783
marci@338
   784
//    int nodeNum() const { return graph->nodeNum(); }
marci@263
   785
    //FIXME
marci@338
   786
    void edgeNum() const { }
marci@303
   787
    //int edgeNum() const { return graph->edgeNum(); }
marci@263
   788
marci@263
   789
marci@317
   790
//    int id(Node v) const { return graph->id(v); }
marci@155
   791
marci@317
   792
    bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@174
   793
    bool valid(Edge e) const { 
marci@389
   794
      return this->graph->valid(e);
marci@317
   795
	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@317
   796
    }
marci@155
   797
marci@174
   798
    void augment(const Edge& e, Number a) const {
marci@317
   799
      if (e.forward)  
marci@303
   800
// 	flow->set(e.out, flow->get(e.out)+a);
marci@317
   801
	flow->set(e, (*flow)[e]+a);
marci@168
   802
      else  
marci@303
   803
// 	flow->set(e.in, flow->get(e.in)-a);
marci@317
   804
	flow->set(e, (*flow)[e]-a);
marci@168
   805
    }
marci@168
   806
marci@269
   807
    Number resCap(const Edge& e) const { 
marci@317
   808
      if (e.forward) 
marci@303
   809
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@317
   810
	return ((*capacity)[e]-(*flow)[e]); 
marci@168
   811
      else 
marci@303
   812
//	return (flow->get(e.in)); 
marci@317
   813
	return ((*flow)[e]); 
marci@168
   814
    }
marci@168
   815
marci@317
   816
//     Number resCap(typename Graph::OutEdgeIt out) const { 
marci@317
   817
// //      return (capacity->get(out)-flow->get(out)); 
marci@317
   818
//       return ((*capacity)[out]-(*flow)[out]); 
marci@317
   819
//     }
marci@168
   820
    
marci@317
   821
//     Number resCap(typename Graph::InEdgeIt in) const { 
marci@317
   822
// //      return (flow->get(in)); 
marci@317
   823
//       return ((*flow)[in]); 
marci@317
   824
//     }
marci@168
   825
marci@155
   826
    template <typename T>
marci@155
   827
    class EdgeMap {
marci@389
   828
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@155
   829
    public:
marci@330
   830
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@330
   831
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@174
   832
      void set(Edge e, T a) { 
marci@317
   833
	if (e.forward) 
marci@155
   834
	  forward_map.set(e.out, a); 
marci@155
   835
	else 
marci@155
   836
	  backward_map.set(e.in, a); 
marci@155
   837
      }
marci@303
   838
      T operator[](Edge e) const { 
marci@317
   839
	if (e.forward) 
marci@303
   840
	  return forward_map[e.out]; 
marci@155
   841
	else 
marci@303
   842
	  return backward_map[e.in]; 
marci@155
   843
      }
marci@303
   844
//       T get(Edge e) const { 
marci@303
   845
// 	if (e.out_or_in) 
marci@303
   846
// 	  return forward_map.get(e.out); 
marci@303
   847
// 	else 
marci@303
   848
// 	  return backward_map.get(e.in); 
marci@303
   849
//       }
marci@155
   850
    };
marci@168
   851
  };
marci@168
   852
marci@338
   853
  /// ErasingFirstGraphWrapper for blocking flows.
marci@317
   854
marci@338
   855
  /// ErasingFirstGraphWrapper for blocking flows.
alpar@457
   856
  ///
alpar@457
   857
  ///\author Marton Makai
marci@303
   858
  template<typename Graph, typename FirstOutEdgesMap>
marci@303
   859
  class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@269
   860
  protected:
marci@269
   861
    FirstOutEdgesMap* first_out_edges;
marci@269
   862
  public:
marci@303
   863
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@303
   864
			     FirstOutEdgesMap& _first_out_edges) : 
marci@303
   865
      GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@269
   866
marci@317
   867
    typedef typename GraphWrapper<Graph>::Node Node;
marci@338
   868
//     class NodeIt { 
marci@338
   869
//       friend class GraphWrapper<Graph>;
marci@338
   870
//       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@338
   871
//       typename Graph::NodeIt n;
marci@338
   872
//      public:
marci@338
   873
//       NodeIt() { }
marci@338
   874
//       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@338
   875
//       NodeIt(const Invalid& i) : n(i) { }
marci@338
   876
//       NodeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@338
   877
// 	n(*(_G.graph)) { }
marci@338
   878
//       operator Node() const { return Node(typename Graph::Node(n)); }
marci@338
   879
//     };
marci@317
   880
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317
   881
    class OutEdgeIt { 
marci@317
   882
      friend class GraphWrapper<Graph>;
marci@317
   883
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317
   884
//      typedef typename Graph::OutEdgeIt GraphOutEdgeIt;
marci@317
   885
      typename Graph::OutEdgeIt e;
marci@311
   886
    public:
marci@311
   887
      OutEdgeIt() { }
marci@317
   888
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317
   889
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@311
   890
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@317
   891
		const Node& _n) : 
marci@317
   892
	e((*_G.first_out_edges)[_n]) { }
marci@317
   893
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   894
    };
marci@317
   895
    class InEdgeIt { 
marci@317
   896
      friend class GraphWrapper<Graph>;
marci@317
   897
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317
   898
//      typedef typename Graph::InEdgeIt GraphInEdgeIt;
marci@317
   899
      typename Graph::InEdgeIt e;
marci@311
   900
    public:
marci@311
   901
      InEdgeIt() { }
marci@317
   902
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317
   903
      InEdgeIt(const Invalid& i) : e(i) { }
marci@311
   904
      InEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@317
   905
	       const Node& _n) : 
marci@317
   906
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317
   907
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   908
    };
marci@311
   909
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317
   910
    class EdgeIt { 
marci@317
   911
      friend class GraphWrapper<Graph>;
marci@317
   912
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317
   913
//      typedef typename Graph::EdgeIt GraphEdgeIt;
marci@317
   914
      typename Graph::EdgeIt e;
marci@311
   915
    public:
marci@311
   916
      EdgeIt() { }
marci@317
   917
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317
   918
      EdgeIt(const Invalid& i) : e(i) { }
marci@311
   919
      EdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@317
   920
	e(*(_G.graph)) { }
marci@317
   921
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   922
    };
marci@311
   923
marci@338
   924
    using GraphWrapper<Graph>::first;
marci@338
   925
//     NodeIt& first(NodeIt& i) const { 
marci@338
   926
//       i=NodeIt(*this); return i;
marci@338
   927
//     }
marci@317
   928
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   929
      i=OutEdgeIt(*this, p); return i;
marci@269
   930
    }
marci@317
   931
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   932
      i=InEdgeIt(*this, p); return i;
marci@311
   933
    }
marci@317
   934
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   935
      i=EdgeIt(*this); return i;
marci@311
   936
    }
marci@311
   937
marci@338
   938
    using GraphWrapper<Graph>::next;
marci@338
   939
//    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@389
   940
    OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389
   941
    InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389
   942
    EdgeIt& next(EdgeIt& i) const { this->graph->next(i.e); return i; }    
marci@317
   943
    
marci@389
   944
    Node aNode(const OutEdgeIt& e) const { 
marci@389
   945
      return Node(this->graph->aNode(e.e)); }
marci@389
   946
    Node aNode(const InEdgeIt& e) const { 
marci@389
   947
      return Node(this->graph->aNode(e.e)); }
marci@389
   948
    Node bNode(const OutEdgeIt& e) const { 
marci@389
   949
      return Node(this->graph->bNode(e.e)); }
marci@389
   950
    Node bNode(const InEdgeIt& e) const { 
marci@389
   951
      return Node(this->graph->bNode(e.e)); }
marci@311
   952
marci@269
   953
    void erase(const OutEdgeIt& e) const {
marci@269
   954
      OutEdgeIt f=e;
marci@269
   955
      this->next(f);
marci@317
   956
      first_out_edges->set(this->tail(e), f.e);
marci@269
   957
    }
marci@269
   958
  };
marci@269
   959
alpar@406
   960
  ///@}
marci@341
   961
alpar@105
   962
} //namespace hugo
marci@76
   963
alpar@406
   964
marci@259
   965
#endif //HUGO_GRAPH_WRAPPER_H
marci@76
   966