src/hugo/graph_wrapper.h
author deba
Wed, 08 Sep 2004 12:06:45 +0000
changeset 822 88226d9fe821
parent 777 a82713ed19f3
child 838 51dcd224455c
permissions -rw-r--r--
The MapFactories have been removed from the code because
if we use macros then they increases only the complexity.

The pair iterators of the maps are separeted from the maps.

Some macros and comments has been changed.
marci@556
     1
// -*- c++ -*-
marci@556
     2
#ifndef HUGO_GRAPH_WRAPPER_H
marci@556
     3
#define HUGO_GRAPH_WRAPPER_H
marci@556
     4
marci@556
     5
///\ingroup gwrappers
marci@556
     6
///\file
marci@556
     7
///\brief Several graph wrappers.
marci@556
     8
///
marci@556
     9
///This file contains several useful graph wrapper functions.
marci@556
    10
///
marci@556
    11
///\author Marton Makai
marci@556
    12
marci@556
    13
#include <hugo/invalid.h>
marci@650
    14
#include <hugo/maps.h>
alpar@774
    15
#include <iostream>
marci@556
    16
marci@556
    17
namespace hugo {
marci@556
    18
marci@556
    19
  // Graph wrappers
marci@556
    20
marci@556
    21
  /// \addtogroup gwrappers
marci@556
    22
  /// A main parts of HUGOlib are the different graph structures, 
marci@556
    23
  /// generic graph algorithms, graph concepts which couple these, and 
marci@556
    24
  /// graph wrappers. While the previous ones are more or less clear, the 
marci@556
    25
  /// latter notion needs further explanation.
marci@556
    26
  /// Graph wrappers are graph classes which serve for considering graph 
marci@556
    27
  /// structures in different ways. A short example makes the notion much 
marci@556
    28
  /// clearer. 
marci@556
    29
  /// Suppose that we have an instance \c g of a directed graph
marci@556
    30
  /// type say \c ListGraph and an algorithm 
marci@556
    31
  /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
marci@556
    32
  /// is needed to run on the reversely oriented graph. 
marci@556
    33
  /// It may be expensive (in time or in memory usage) to copy 
marci@556
    34
  /// \c g with the reverse orientation. 
marci@556
    35
  /// Thus, a wrapper class
marci@556
    36
  /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@556
    37
  /// The code looks as follows
marci@556
    38
  /// \code
marci@556
    39
  /// ListGraph g;
marci@556
    40
  /// RevGraphWrapper<ListGraph> rgw(g);
marci@556
    41
  /// int result=algorithm(rgw);
marci@556
    42
  /// \endcode
marci@556
    43
  /// After running the algorithm, the original graph \c g 
marci@556
    44
  /// remains untouched. Thus the graph wrapper used above is to consider the 
marci@556
    45
  /// original graph with reverse orientation. 
marci@556
    46
  /// This techniques gives rise to an elegant code, and 
marci@556
    47
  /// based on stable graph wrappers, complex algorithms can be 
marci@556
    48
  /// implemented easily. 
marci@556
    49
  /// In flow, circulation and bipartite matching problems, the residual 
marci@556
    50
  /// graph is of particular importance. Combining a wrapper implementing 
marci@556
    51
  /// this, shortest path algorithms and minimum mean cycle algorithms, 
marci@556
    52
  /// a range of weighted and cardinality optimization algorithms can be 
marci@556
    53
  /// obtained. For lack of space, for other examples, 
marci@556
    54
  /// the interested user is referred to the detailed documentation of graph 
marci@556
    55
  /// wrappers. 
marci@556
    56
  /// The behavior of graph wrappers can be very different. Some of them keep 
marci@556
    57
  /// capabilities of the original graph while in other cases this would be 
marci@556
    58
  /// meaningless. This means that the concepts that they are a model of depend 
marci@556
    59
  /// on the graph wrapper, and the wrapped graph(s). 
marci@556
    60
  /// If an edge of \c rgw is deleted, this is carried out by 
marci@556
    61
  /// deleting the corresponding edge of \c g. But for a residual 
marci@556
    62
  /// graph, this operation has no sense. 
marci@556
    63
  /// Let we stand one more example here to simplify your work. 
marci@556
    64
  /// wrapper class
marci@556
    65
  /// \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@556
    66
  /// has constructor 
marci@556
    67
  /// <tt> RevGraphWrapper(Graph& _g)</tt>. 
marci@556
    68
  /// This means that in a situation, 
marci@556
    69
  /// when a <tt> const ListGraph& </tt> reference to a graph is given, 
marci@556
    70
  /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
marci@556
    71
  /// \code
marci@556
    72
  /// int algorithm1(const ListGraph& g) {
marci@556
    73
  ///   RevGraphWrapper<const ListGraph> rgw(g);
marci@556
    74
  ///   return algorithm2(rgw);
marci@556
    75
  /// }
marci@556
    76
  /// \endcode
marci@556
    77
marci@556
    78
  /// \addtogroup gwrappers
marci@556
    79
  /// @{
marci@556
    80
marci@556
    81
  ///Base type for the Graph Wrappers
marci@556
    82
marci@556
    83
  ///This is the base type for the Graph Wrappers.
marci@556
    84
  ///\todo Some more docs... 
marci@556
    85
  ///
marci@612
    86
  ///\author Marton Makai 
marci@556
    87
  template<typename Graph>
marci@556
    88
  class GraphWrapper {
marci@556
    89
  protected:
marci@556
    90
    Graph* graph;
marci@556
    91
    GraphWrapper() : graph(0) { }
marci@556
    92
    void setGraph(Graph& _graph) { graph=&_graph; }
marci@556
    93
marci@556
    94
  public:
marci@556
    95
    typedef Graph BaseGraph;
marci@556
    96
    typedef Graph ParentGraph;
marci@556
    97
marci@556
    98
    GraphWrapper(Graph& _graph) : graph(&_graph) { }
alpar@774
    99
    GraphWrapper(const GraphWrapper<Graph>& gw) : graph(gw.graph) { }
marci@556
   100
//     Graph& getGraph() const { return *graph; }
marci@556
   101
 
alpar@774
   102
    typedef typename Graph::Node Node;
alpar@774
   103
    class NodeIt : public Node { 
alpar@774
   104
      const GraphWrapper<Graph>* gw;
marci@556
   105
      friend class GraphWrapper<Graph>;
marci@556
   106
     public:
marci@556
   107
      NodeIt() { }
alpar@774
   108
      //      NodeIt(const NodeIt& n) : Node(n), gw(n.gw) { }
alpar@774
   109
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   110
      NodeIt(const GraphWrapper<Graph>& _gw) : 
alpar@774
   111
	Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { }
alpar@774
   112
      NodeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   113
	Node(n), gw(&_gw) { }
alpar@774
   114
      NodeIt& operator++() { 
alpar@774
   115
	*(static_cast<Node*>(this))=
alpar@774
   116
	  ++(typename Graph::NodeIt(*(gw->graph), *this));
alpar@774
   117
	return *this; 
alpar@774
   118
      }
marci@556
   119
    };
alpar@774
   120
    typedef typename Graph::Edge Edge;
alpar@774
   121
    class OutEdgeIt : public Edge { 
alpar@774
   122
      const GraphWrapper<Graph>* gw;
marci@556
   123
      friend class GraphWrapper<Graph>;
alpar@774
   124
     public:
alpar@774
   125
      OutEdgeIt() { }
alpar@774
   126
      //OutEdgeIt(const OutEdgeIt& e) : Edge(e), gw(e.gw) { }
alpar@774
   127
      OutEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   128
      OutEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   129
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   130
      OutEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   131
	Edge(e), gw(&_gw) { }
alpar@774
   132
      OutEdgeIt& operator++() { 
alpar@774
   133
	*(static_cast<Edge*>(this))=
alpar@774
   134
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   135
	return *this; 
alpar@774
   136
      }
marci@556
   137
    };
alpar@774
   138
    class InEdgeIt : public Edge { 
alpar@774
   139
      const GraphWrapper<Graph>* gw;
marci@556
   140
      friend class GraphWrapper<Graph>;
alpar@774
   141
     public:
marci@556
   142
      InEdgeIt() { }
alpar@774
   143
      //InEdgeIt(const InEdgeIt& e) : Edge(e), gw(e.gw) { }
alpar@774
   144
      InEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   145
      InEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   146
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   147
      InEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   148
	Edge(e), gw(&_gw) { }
alpar@774
   149
      InEdgeIt& operator++() { 
alpar@774
   150
	*(static_cast<Edge*>(this))=
alpar@774
   151
	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   152
	return *this; 
alpar@774
   153
      }
marci@556
   154
    };
marci@556
   155
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
alpar@774
   156
    class EdgeIt : public Edge { 
alpar@774
   157
      const GraphWrapper<Graph>* gw;
marci@556
   158
      friend class GraphWrapper<Graph>;
alpar@774
   159
     public:
marci@556
   160
      EdgeIt() { }
alpar@774
   161
      //EdgeIt(const EdgeIt& e) : Edge(e), gw(e.gw) { }
alpar@774
   162
      EdgeIt(Invalid i) : Edge(i) { }
alpar@774
   163
      EdgeIt(const GraphWrapper<Graph>& _gw) : 
alpar@774
   164
	Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { }
alpar@774
   165
      EdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
marci@777
   166
	Edge(e), gw(&_gw) { }
alpar@774
   167
      EdgeIt& operator++() { 
alpar@774
   168
	*(static_cast<Edge*>(this))=
alpar@774
   169
	  ++(typename Graph::EdgeIt(*(gw->graph), *this));
alpar@774
   170
	return *this; 
alpar@774
   171
      }
marci@556
   172
    };
marci@556
   173
   
marci@556
   174
    NodeIt& first(NodeIt& i) const { 
marci@556
   175
      i=NodeIt(*this); return i;
marci@556
   176
    }
marci@556
   177
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   178
      i=OutEdgeIt(*this, p); return i;
marci@556
   179
    }
marci@556
   180
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   181
      i=InEdgeIt(*this, p); return i;
marci@556
   182
    }
marci@556
   183
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   184
      i=EdgeIt(*this); return i;
marci@556
   185
    }
marci@556
   186
alpar@774
   187
//     NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
alpar@774
   188
//     OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
alpar@774
   189
//     InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
alpar@774
   190
//     EdgeIt& next(EdgeIt& i) const { graph->next(i.e); return i; }    
marci@556
   191
marci@556
   192
    Node tail(const Edge& e) const { 
marci@556
   193
      return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
marci@556
   194
    Node head(const Edge& e) const { 
marci@556
   195
      return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
marci@556
   196
alpar@774
   197
//     bool valid(const Node& n) const { 
alpar@774
   198
//       return graph->valid(static_cast<typename Graph::Node>(n)); }
alpar@774
   199
//     bool valid(const Edge& e) const { 
alpar@774
   200
//       return graph->valid(static_cast<typename Graph::Edge>(e)); }
marci@556
   201
marci@556
   202
    int nodeNum() const { return graph->nodeNum(); }
marci@556
   203
    int edgeNum() const { return graph->edgeNum(); }
marci@556
   204
  
alpar@774
   205
//     Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
alpar@774
   206
//     Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
alpar@774
   207
//     Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
alpar@774
   208
//     Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@556
   209
  
marci@556
   210
    Node addNode() const { return Node(graph->addNode()); }
marci@556
   211
    Edge addEdge(const Node& tail, const Node& head) const { 
marci@556
   212
      return Edge(graph->addEdge(tail, head)); }
marci@556
   213
marci@556
   214
    void erase(const Node& i) const { graph->erase(i); }
marci@556
   215
    void erase(const Edge& i) const { graph->erase(i); }
marci@556
   216
  
marci@556
   217
    void clear() const { graph->clear(); }
marci@556
   218
    
alpar@736
   219
    bool forward(const Edge& e) const { return graph->forward(e); }
alpar@736
   220
    bool backward(const Edge& e) const { return graph->backward(e); }
marci@739
   221
marci@739
   222
    int id(const Node& v) const { return graph->id(v); }
marci@739
   223
    int id(const Edge& e) const { return graph->id(e); }
marci@650
   224
    
marci@738
   225
    Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); }
marci@650
   226
marci@556
   227
    template<typename T> class NodeMap : public Graph::template NodeMap<T> { 
marci@556
   228
      typedef typename Graph::template NodeMap<T> Parent;
marci@556
   229
    public:
alpar@774
   230
      NodeMap(const GraphWrapper<Graph>& gw) :  Parent(*(gw.graph)) { }
alpar@774
   231
      NodeMap(const GraphWrapper<Graph>& gw, T a) : Parent(*(gw.graph), a) { }
marci@556
   232
    };
marci@556
   233
marci@556
   234
    template<typename T> class EdgeMap : public Graph::template EdgeMap<T> { 
marci@556
   235
      typedef typename Graph::template EdgeMap<T> Parent;
marci@556
   236
    public:
alpar@774
   237
      EdgeMap(const GraphWrapper<Graph>& gw) : Parent(*(gw.graph)) { }
alpar@774
   238
      EdgeMap(const GraphWrapper<Graph>& gw, T a) : Parent(*(gw.graph), a) { }
marci@556
   239
    };
marci@556
   240
  };
marci@556
   241
marci@569
   242
marci@569
   243
marci@556
   244
  /// A graph wrapper which reverses the orientation of the edges.
marci@556
   245
marci@556
   246
  /// A graph wrapper which reverses the orientation of the edges.
marci@612
   247
  /// Thus \c Graph have to be a directed graph type.
marci@556
   248
  ///
marci@556
   249
  ///\author Marton Makai
marci@556
   250
  template<typename Graph>
marci@556
   251
  class RevGraphWrapper : public GraphWrapper<Graph> {
marci@650
   252
  public:
marci@650
   253
    typedef GraphWrapper<Graph> Parent; 
marci@556
   254
  protected:
marci@612
   255
    RevGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   256
  public:
marci@556
   257
    RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
alpar@774
   258
    RevGraphWrapper(const RevGraphWrapper<Graph>& gw) : Parent(gw) { }
marci@556
   259
marci@556
   260
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   261
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@792
   262
    //remark: OutEdgeIt and InEdgeIt cannot be typedef-ed to each other
marci@792
   263
    //because this does not work is some of them are not defined in the 
marci@792
   264
    //original graph. The problem with this is that typedef-ed stuff 
marci@792
   265
    //are instantiated in c++.
alpar@774
   266
    class OutEdgeIt : public Edge { 
alpar@774
   267
      const RevGraphWrapper<Graph>* gw;
marci@556
   268
      friend class GraphWrapper<Graph>;
alpar@774
   269
     public:
marci@556
   270
      OutEdgeIt() { }
alpar@774
   271
      //OutEdgeIt(const OutEdgeIt& e) : Edge(e), gw(e.gw) { }
alpar@774
   272
      OutEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   273
      OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   274
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   275
      OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   276
	Edge(e), gw(&_gw) { }
alpar@774
   277
      OutEdgeIt& operator++() { 
alpar@774
   278
	*(static_cast<Edge*>(this))=
alpar@774
   279
	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   280
	return *this; 
alpar@774
   281
      }
marci@556
   282
    };
alpar@774
   283
    class InEdgeIt : public Edge { 
alpar@774
   284
      const RevGraphWrapper<Graph>* gw;
marci@556
   285
      friend class GraphWrapper<Graph>;
alpar@774
   286
     public:
marci@556
   287
      InEdgeIt() { }
alpar@774
   288
      //InEdgeIt(const InEdgeIt& e) : Edge(e), gw(e.gw) { }
alpar@774
   289
      InEdgeIt(Invalid i) : Edge(i) { }
alpar@774
   290
      InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) : 
alpar@774
   291
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
alpar@774
   292
      InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) : 
alpar@774
   293
	Edge(e), gw(&_gw) { }
alpar@774
   294
      InEdgeIt& operator++() { 
alpar@774
   295
	*(static_cast<Edge*>(this))=
alpar@774
   296
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   297
	return *this; 
alpar@774
   298
      }
marci@556
   299
    };
marci@556
   300
marci@556
   301
    using GraphWrapper<Graph>::first;
marci@556
   302
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   303
      i=OutEdgeIt(*this, p); return i;
marci@556
   304
    }
marci@556
   305
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   306
      i=InEdgeIt(*this, p); return i;
marci@556
   307
    }
marci@556
   308
alpar@774
   309
//     using GraphWrapper<Graph>::next;
alpar@774
   310
//     OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
alpar@774
   311
//     InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   312
alpar@774
   313
//     Node aNode(const OutEdgeIt& e) const { 
alpar@774
   314
//       return Node(this->graph->aNode(e.e)); }
alpar@774
   315
//     Node aNode(const InEdgeIt& e) const { 
alpar@774
   316
//       return Node(this->graph->aNode(e.e)); }
alpar@774
   317
//     Node bNode(const OutEdgeIt& e) const { 
alpar@774
   318
//       return Node(this->graph->bNode(e.e)); }
alpar@774
   319
//     Node bNode(const InEdgeIt& e) const { 
alpar@774
   320
//       return Node(this->graph->bNode(e.e)); }
marci@556
   321
marci@556
   322
    Node tail(const Edge& e) const { 
marci@556
   323
      return GraphWrapper<Graph>::head(e); }
marci@556
   324
    Node head(const Edge& e) const { 
marci@556
   325
      return GraphWrapper<Graph>::tail(e); }
marci@556
   326
marci@556
   327
  };
marci@556
   328
marci@775
   329
marci@775
   330
marci@612
   331
  /// A graph wrapper for hiding nodes and edges from a graph.
marci@556
   332
  
marci@556
   333
  /// This wrapper shows a graph with filtered node-set and 
marci@556
   334
  /// edge-set. The quick brown fox iterator jumps over 
marci@556
   335
  /// the lazy dog nodes or edges if the values for them are false 
marci@556
   336
  /// in the bool maps. 
marci@556
   337
  ///
marci@556
   338
  ///\author Marton Makai
marci@556
   339
  template<typename Graph, typename NodeFilterMap, 
marci@556
   340
	   typename EdgeFilterMap>
marci@556
   341
  class SubGraphWrapper : public GraphWrapper<Graph> {
marci@650
   342
  public:
marci@650
   343
    typedef GraphWrapper<Graph> Parent;
marci@556
   344
  protected:
marci@556
   345
    NodeFilterMap* node_filter_map;
marci@556
   346
    EdgeFilterMap* edge_filter_map;
marci@556
   347
marci@612
   348
    SubGraphWrapper() : GraphWrapper<Graph>(), 
marci@556
   349
			node_filter_map(0), edge_filter_map(0) { }
marci@556
   350
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
marci@556
   351
      node_filter_map=&_node_filter_map;
marci@556
   352
    }
marci@556
   353
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
marci@556
   354
      edge_filter_map=&_edge_filter_map;
marci@556
   355
    }
marci@556
   356
    
marci@556
   357
  public:
marci@556
   358
    SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@556
   359
		    EdgeFilterMap& _edge_filter_map) : 
marci@556
   360
      GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
marci@556
   361
      edge_filter_map(&_edge_filter_map) { }  
marci@556
   362
marci@556
   363
    typedef typename GraphWrapper<Graph>::Node Node;
marci@775
   364
    class NodeIt : public Node { 
marci@775
   365
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   366
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@775
   367
    public:
marci@556
   368
      NodeIt() { }
marci@775
   369
      //      NodeIt(const NodeIt& n) : Node(n), gw(n.gw) { }
marci@775
   370
      NodeIt(Invalid i) : Node(i) { }
marci@775
   371
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) : 
marci@775
   372
	Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { }
marci@775
   373
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   374
	     const Node& n) : 
marci@775
   375
	Node(n), gw(&_gw) { }
marci@775
   376
      NodeIt& operator++() { 
marci@775
   377
	*(static_cast<Node*>(this))=
marci@775
   378
	  ++(typename Graph::NodeIt(*(gw->graph), *this));
marci@775
   379
	while (*static_cast<Node*>(this)!=INVALID && 
marci@775
   380
	       !(*(gw->node_filter_map))[*this]) 
marci@775
   381
	  *(static_cast<Node*>(this))=
marci@775
   382
	    ++(typename Graph::NodeIt(*(gw->graph), *this));
marci@775
   383
	return *this; 
marci@556
   384
      }
marci@556
   385
    };
marci@556
   386
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@775
   387
    class OutEdgeIt : public Edge { 
marci@775
   388
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   389
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   390
    public:
marci@556
   391
      OutEdgeIt() { }
marci@775
   392
      //      OutEdgeIt(const OutEdgeIt& e) : Edge(e), gw(e.gw) { }
marci@775
   393
      OutEdgeIt(Invalid i) : Edge(i) { }
marci@775
   394
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) : 
marci@777
   395
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
marci@775
   396
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   397
	     const Edge& e) : 
marci@775
   398
	Edge(e), gw(&_gw) { }
marci@775
   399
      OutEdgeIt& operator++() { 
marci@775
   400
	*(static_cast<Edge*>(this))=
marci@775
   401
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   402
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@775
   403
	       !(*(gw->edge_filter_map))[*this]) 
marci@775
   404
	  *(static_cast<Edge*>(this))=
marci@775
   405
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   406
	return *this; 
marci@556
   407
      }
marci@556
   408
    };
marci@775
   409
    class InEdgeIt : public Edge { 
marci@775
   410
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   411
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   412
    public:
marci@556
   413
      InEdgeIt() { }
marci@775
   414
      //      InEdgeIt(const InEdgeIt& e) : Edge(e), gw(e.gw) { }
marci@775
   415
      InEdgeIt(Invalid i) : Edge(i) { }
marci@775
   416
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) : 
marci@777
   417
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
marci@775
   418
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   419
	     const Edge& e) : 
marci@775
   420
	Edge(e), gw(&_gw) { }
marci@775
   421
      InEdgeIt& operator++() { 
marci@775
   422
	*(static_cast<Edge*>(this))=
marci@775
   423
	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   424
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@775
   425
	       !(*(gw->edge_filter_map))[*this]) 
marci@775
   426
	  *(static_cast<Edge*>(this))=
marci@775
   427
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   428
	return *this; 
marci@556
   429
      }
marci@556
   430
    };
marci@775
   431
    class EdgeIt : public Edge { 
marci@775
   432
      const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
marci@556
   433
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   434
    public:
marci@556
   435
      EdgeIt() { }
marci@775
   436
      //      EdgeIt(const EdgeIt& e) : Edge(e), gw(e.gw) { }
marci@775
   437
      EdgeIt(Invalid i) : Edge(i) { }
marci@775
   438
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) : 
marci@775
   439
	Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { }
marci@775
   440
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
marci@775
   441
	     const Edge& e) : 
marci@775
   442
	Edge(e), gw(&_gw) { }
marci@775
   443
      EdgeIt& operator++() { 
marci@775
   444
	*(static_cast<Edge*>(this))=
marci@775
   445
	  ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   446
	while (*static_cast<Edge*>(this)!=INVALID && 
marci@775
   447
	       !(*(gw->edge_filter_map))[*this]) 
marci@775
   448
	  *(static_cast<Edge*>(this))=
marci@775
   449
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   450
	return *this; 
marci@556
   451
      }
marci@556
   452
    };
marci@556
   453
marci@556
   454
    NodeIt& first(NodeIt& i) const { 
marci@556
   455
      i=NodeIt(*this); return i;
marci@556
   456
    }
marci@556
   457
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   458
      i=OutEdgeIt(*this, p); return i;
marci@556
   459
    }
marci@556
   460
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   461
      i=InEdgeIt(*this, p); return i;
marci@556
   462
    }
marci@556
   463
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   464
      i=EdgeIt(*this); return i;
marci@556
   465
    }
marci@556
   466
    
marci@775
   467
//     NodeIt& next(NodeIt& i) const {
marci@775
   468
//       this->graph->next(i.n); 
marci@775
   469
//       while (this->graph->valid(i) && !(*node_filter_map)[i.n]) { 
marci@775
   470
// 	this->graph->next(i.n); }
marci@775
   471
//       return i;
marci@775
   472
//     }
marci@775
   473
//     OutEdgeIt& next(OutEdgeIt& i) const {
marci@775
   474
//       this->graph->next(i.e); 
marci@775
   475
//       while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@775
   476
// 	this->graph->next(i.e); }
marci@775
   477
//       return i;
marci@775
   478
//     }
marci@775
   479
//     InEdgeIt& next(InEdgeIt& i) const {
marci@775
   480
//       this->graph->next(i.e); 
marci@775
   481
//       while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@775
   482
// 	this->graph->next(i.e); }
marci@775
   483
//       return i;
marci@775
   484
//     }
marci@775
   485
//     EdgeIt& next(EdgeIt& i) const {
marci@775
   486
//       this->graph->next(i.e); 
marci@775
   487
//       while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@775
   488
// 	this->graph->next(i.e); }
marci@775
   489
//       return i;
marci@775
   490
//     }
marci@556
   491
marci@775
   492
//     Node aNode(const OutEdgeIt& e) const { 
marci@775
   493
//       return Node(this->graph->aNode(e.e)); }
marci@775
   494
//     Node aNode(const InEdgeIt& e) const { 
marci@775
   495
//       return Node(this->graph->aNode(e.e)); }
marci@775
   496
//     Node bNode(const OutEdgeIt& e) const { 
marci@775
   497
//       return Node(this->graph->bNode(e.e)); }
marci@775
   498
//     Node bNode(const InEdgeIt& e) const { 
marci@775
   499
//       return Node(this->graph->bNode(e.e)); }
marci@556
   500
marci@561
   501
    /// This function hides \c n in the graph, i.e. the iteration 
marci@561
   502
    /// jumps over it. This is done by simply setting the value of \c n  
marci@561
   503
    /// to be false in the corresponding node-map.
marci@556
   504
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@561
   505
marci@561
   506
    /// This function hides \c e in the graph, i.e. the iteration 
marci@561
   507
    /// jumps over it. This is done by simply setting the value of \c e  
marci@561
   508
    /// to be false in the corresponding edge-map.
marci@556
   509
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@556
   510
marci@561
   511
    /// The value of \c n is set to be true in the node-map which stores 
marci@561
   512
    /// hide information. If \c n was hidden previuosly, then it is shown 
marci@561
   513
    /// again
marci@561
   514
     void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@561
   515
marci@561
   516
    /// The value of \c e is set to be true in the edge-map which stores 
marci@561
   517
    /// hide information. If \c e was hidden previuosly, then it is shown 
marci@561
   518
    /// again
marci@556
   519
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@556
   520
marci@561
   521
    /// Returns true if \c n is hidden.
marci@561
   522
    bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
marci@561
   523
marci@561
   524
    /// Returns true if \c n is hidden.
marci@561
   525
    bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
marci@593
   526
marci@792
   527
    /// \warning This is a linear time operation and works only if 
marci@792
   528
    /// \c Graph::NodeIt is defined.
marci@593
   529
    int nodeNum() const { 
marci@593
   530
      int i=0;
marci@792
   531
      for (NodeIt n(*this); n!=INVALID; ++n) ++i;
marci@593
   532
      return i; 
marci@593
   533
    }
marci@593
   534
marci@792
   535
    /// \warning This is a linear time operation and works only if 
marci@792
   536
    /// \c Graph::EdgeIt is defined.
marci@593
   537
    int edgeNum() const { 
marci@593
   538
      int i=0;
marci@792
   539
      for (EdgeIt e(*this); e!=INVALID; ++e) ++i;
marci@593
   540
      return i; 
marci@593
   541
    }
marci@593
   542
marci@556
   543
  };
marci@556
   544
marci@569
   545
marci@569
   546
marci@612
   547
  /// \brief A wrapper for forgetting the orientation of a graph.
marci@612
   548
  ///
marci@556
   549
  /// A wrapper for getting an undirected graph by forgetting
marci@556
   550
  /// the orientation of a directed one.
alpar@589
   551
  ///
marci@612
   552
  /// \author Marton Makai
marci@556
   553
  template<typename Graph>
marci@556
   554
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@650
   555
  public:
marci@650
   556
    typedef GraphWrapper<Graph> Parent; 
marci@556
   557
  protected:
marci@556
   558
    UndirGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   559
    
marci@556
   560
  public:
marci@556
   561
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   562
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   563
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   564
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@556
   565
marci@556
   566
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@556
   567
marci@556
   568
    class OutEdgeIt {
marci@556
   569
      friend class UndirGraphWrapper<Graph>;
marci@556
   570
      bool out_or_in; //true iff out
marci@556
   571
      typename Graph::OutEdgeIt out;
marci@556
   572
      typename Graph::InEdgeIt in;
marci@556
   573
    public:
marci@556
   574
      OutEdgeIt() { }
marci@556
   575
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@556
   576
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@556
   577
	out_or_in=true; _G.graph->first(out, _n);
marci@556
   578
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@556
   579
      } 
marci@556
   580
      operator Edge() const { 
marci@556
   581
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@556
   582
      }
marci@556
   583
    };
marci@556
   584
marci@556
   585
//FIXME InEdgeIt
marci@556
   586
    typedef OutEdgeIt InEdgeIt; 
marci@556
   587
marci@556
   588
    using GraphWrapper<Graph>::first;
marci@556
   589
//     NodeIt& first(NodeIt& i) const { 
marci@556
   590
//       i=NodeIt(*this); return i;
marci@556
   591
//     }
marci@556
   592
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   593
      i=OutEdgeIt(*this, p); return i;
marci@556
   594
    }
marci@556
   595
//FIXME
marci@556
   596
//     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   597
//       i=InEdgeIt(*this, p); return i;
marci@556
   598
//     }
marci@556
   599
//     EdgeIt& first(EdgeIt& i) const { 
marci@556
   600
//       i=EdgeIt(*this); return i;
marci@556
   601
//     }
marci@556
   602
marci@556
   603
    using GraphWrapper<Graph>::next;
marci@556
   604
//     NodeIt& next(NodeIt& n) const {
marci@556
   605
//       GraphWrapper<Graph>::next(n);
marci@556
   606
//       return n;
marci@556
   607
//     }
marci@556
   608
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@556
   609
      if (e.out_or_in) {
marci@556
   610
	typename Graph::Node n=this->graph->tail(e.out);
marci@556
   611
	this->graph->next(e.out);
marci@556
   612
	if (!this->graph->valid(e.out)) { 
marci@556
   613
	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@556
   614
      } else {
marci@556
   615
	this->graph->next(e.in);
marci@556
   616
      }
marci@556
   617
      return e;
marci@556
   618
    }
marci@556
   619
    //FIXME InEdgeIt
marci@556
   620
//     EdgeIt& next(EdgeIt& e) const {
marci@556
   621
//       GraphWrapper<Graph>::next(n);
marci@556
   622
// //      graph->next(e.e);
marci@556
   623
//       return e;
marci@556
   624
//     }
marci@556
   625
marci@556
   626
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   627
      if (e.out_or_in) return this->graph->tail(e); else 
marci@556
   628
	return this->graph->head(e); }
marci@556
   629
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   630
      if (e.out_or_in) return this->graph->head(e); else 
marci@556
   631
	return this->graph->tail(e); }
marci@556
   632
  };
marci@556
   633
  
marci@612
   634
  /// \brief An undirected graph template.
marci@612
   635
  ///
marci@612
   636
  /// An undirected graph template.
marci@612
   637
  /// This class works as an undirected graph and a directed graph of 
marci@612
   638
  /// class \c Graph is used for the physical storage.
marci@612
   639
  /// \ingroup graphs
marci@556
   640
  template<typename Graph>
marci@556
   641
  class UndirGraph : public UndirGraphWrapper<Graph> {
marci@556
   642
    typedef UndirGraphWrapper<Graph> Parent;
marci@556
   643
  protected:
marci@556
   644
    Graph gr;
marci@556
   645
  public:
marci@556
   646
    UndirGraph() : UndirGraphWrapper<Graph>() { 
marci@556
   647
      Parent::setGraph(gr); 
marci@556
   648
    }
marci@556
   649
  };
marci@556
   650
marci@569
   651
marci@650
   652
marci@650
   653
  ///\brief A wrapper for composing a subgraph of a 
marci@792
   654
  /// bidirected graph made from a directed one. 
marci@612
   655
  ///
marci@792
   656
  /// Suppose that for a directed graph $G=(V, A)$, 
marci@792
   657
  /// two predicates on the edge-set, $forward_filter$, and $backward_filter$ 
marci@792
   658
  /// is given, and we are dealing with the directed graph
marci@792
   659
  /// a $G'=(V, \{uv : uv\in A \mbox{ and } forward_filter(uv) \mbox{ is true}\}+\{vu : uv\in A \mbox{ and } backward_filter(uv) \mbox{ is true}\})$. 
marci@792
   660
  /// The purpose of writing + instead of union is because parallel 
marci@792
   661
  /// edges can arose. 
marci@792
   662
  /// In other words, a subgraph of the bidirected graph obtained, which 
marci@792
   663
  /// is given by orienting the edges of the original graph in both directions.
marci@792
   664
  /// An example for such a construction is the \c RevGraphWrapper where the 
marci@792
   665
  /// forward_filter is everywhere false and the backward_filter is 
marci@792
   666
  /// everywhere true. We note that for sake of efficiency, 
marci@792
   667
  /// \c RevGraphWrapper is implemented in a different way. 
marci@792
   668
  /// But BidirGraphWrapper is obtained from 
marci@792
   669
  /// SubBidirGraphWrapper by considering everywhere true 
marci@792
   670
  /// predicates both forward_filter and backward_filter. 
marci@792
   671
  /// Finally, one of the most important applications of SubBidirGraphWrapper 
marci@792
   672
  /// is ResGraphWrapper, which stands for the residual graph in directed 
marci@792
   673
  /// flow and circulation problems. 
marci@792
   674
  /// As wrappers usually, the SubBidirGraphWrapper implements the 
marci@792
   675
  /// above mentioned graph structure without its physical storage, 
marci@792
   676
  /// that is the whole stuff eats constant memory. 
marci@792
   677
  /// As the oppositely directed edges are logical different, 
marci@792
   678
  /// the maps are able to attach different values for them. 
marci@650
   679
  template<typename Graph, 
marci@650
   680
	   typename ForwardFilterMap, typename BackwardFilterMap>
marci@650
   681
  class SubBidirGraphWrapper : public GraphWrapper<Graph> {
marci@650
   682
  public:
marci@650
   683
    typedef GraphWrapper<Graph> Parent; 
marci@569
   684
  protected:
marci@650
   685
    ForwardFilterMap* forward_filter;
marci@650
   686
    BackwardFilterMap* backward_filter;
marci@650
   687
marci@792
   688
    SubBidirGraphWrapper() : GraphWrapper<Graph>() { }
marci@650
   689
    void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
marci@650
   690
      forward_filter=&_forward_filter;
marci@650
   691
    }
marci@650
   692
    void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
marci@650
   693
      backward_filter=&_backward_filter;
marci@650
   694
    }
marci@569
   695
marci@569
   696
  public:
marci@569
   697
marci@650
   698
    SubBidirGraphWrapper(Graph& _graph, ForwardFilterMap& _forward_filter, 
marci@650
   699
			 BackwardFilterMap& _backward_filter) : 
marci@650
   700
      GraphWrapper<Graph>(_graph), 
marci@650
   701
      forward_filter(&_forward_filter), backward_filter(&_backward_filter) { }
alpar@774
   702
    SubBidirGraphWrapper(const SubBidirGraphWrapper<Graph, 
alpar@774
   703
			 ForwardFilterMap, BackwardFilterMap>& gw) : 
alpar@774
   704
      Parent(gw), 
alpar@774
   705
      forward_filter(gw.forward_filter), 
alpar@774
   706
      backward_filter(gw.backward_filter) { }
marci@569
   707
marci@569
   708
    class Edge; 
marci@569
   709
    class OutEdgeIt; 
marci@569
   710
    friend class Edge; 
marci@569
   711
    friend class OutEdgeIt; 
marci@569
   712
marci@621
   713
    template<typename T> class EdgeMap;
marci@621
   714
marci@569
   715
    typedef typename GraphWrapper<Graph>::Node Node;
marci@621
   716
alpar@774
   717
    typedef typename Graph::Edge GraphEdge;
marci@792
   718
    /// SubBidirGraphWrapper<..., ..., ...>::Edge is inherited from 
marci@792
   719
    /// Graph::Edge. It contains an extra bool flag which shows if the 
marci@792
   720
    /// edge is the backward version of the original edge.
marci@569
   721
    class Edge : public Graph::Edge {
marci@650
   722
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   723
					ForwardFilterMap, BackwardFilterMap>;
marci@621
   724
      template<typename T> friend class EdgeMap;
marci@569
   725
    protected:
marci@569
   726
      bool backward; //true, iff backward
marci@569
   727
    public:
marci@569
   728
      Edge() { }
marci@792
   729
      /// \todo =false is needed, or causes problems?
marci@792
   730
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@792
   731
      /// original one, otherwise its oppositely directed pair is obtained.
alpar@774
   732
      Edge(const typename Graph::Edge& e, bool _backward/*=false*/) : 
alpar@774
   733
	Graph::Edge(e), backward(_backward) { }
alpar@774
   734
      Edge(Invalid i) : Graph::Edge(i), backward(true) { }
marci@569
   735
//the unique invalid iterator
alpar@774
   736
//       friend bool operator==(const Edge& u, const Edge& v) { 
alpar@774
   737
// 	return (u.backward==v.backward && 
alpar@774
   738
// 		static_cast<typename Graph::Edge>(u)==
alpar@774
   739
// 		static_cast<typename Graph::Edge>(v));
alpar@774
   740
//       } 
alpar@774
   741
//       friend bool operator!=(const Edge& u, const Edge& v) { 
alpar@774
   742
// 	return (u.backward!=v.backward || 
alpar@774
   743
// 		static_cast<typename Graph::Edge>(u)!=
alpar@774
   744
// 		static_cast<typename Graph::Edge>(v));
alpar@774
   745
//       }
alpar@774
   746
      bool operator==(const Edge& v) const { 
alpar@774
   747
	return (this->backward==v.backward && 
alpar@774
   748
		static_cast<typename Graph::Edge>(*this)==
marci@569
   749
		static_cast<typename Graph::Edge>(v));
marci@569
   750
      } 
alpar@774
   751
      bool operator!=(const Edge& v) const { 
alpar@774
   752
	return (this->backward!=v.backward || 
alpar@774
   753
		static_cast<typename Graph::Edge>(*this)!=
marci@569
   754
		static_cast<typename Graph::Edge>(v));
alpar@774
   755
      }
marci@569
   756
    };
marci@569
   757
alpar@774
   758
    class OutEdgeIt : public Edge {
marci@650
   759
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   760
					ForwardFilterMap, BackwardFilterMap>;
marci@569
   761
    protected:
alpar@774
   762
      const SubBidirGraphWrapper<Graph, 
alpar@774
   763
				 ForwardFilterMap, BackwardFilterMap>* gw;
marci@569
   764
    public:
marci@569
   765
      OutEdgeIt() { }
alpar@774
   766
      OutEdgeIt(Invalid i) : Edge(i) { }
marci@569
   767
//the unique invalid iterator
marci@650
   768
      OutEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   769
		ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) : 
alpar@774
   770
	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), false), gw(&_gw) { 
alpar@774
   771
	while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   772
	       !(*(gw->forward_filter))[*this]) 
alpar@774
   773
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   774
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   775
	if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   776
	  *static_cast<Edge*>(this)=
alpar@774
   777
	    Edge(typename Graph::InEdgeIt(*(_gw.graph), n), true);
marci@775
   778
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   779
		 !(*(gw->backward_filter))[*this]) 
marci@775
   780
	    *(static_cast<GraphEdge*>(this))=
marci@775
   781
	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   782
	}
alpar@774
   783
      }
alpar@774
   784
      OutEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   785
		ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
alpar@774
   786
	Edge(e), gw(&_gw) { }
alpar@774
   787
      OutEdgeIt& operator++() { 
alpar@774
   788
	if (!this->backward) {
alpar@774
   789
	  Node n=gw->tail(*this);
alpar@774
   790
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   791
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   792
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   793
		 !(*(gw->forward_filter))[*this]) 
alpar@774
   794
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   795
	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   796
	  if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   797
	    *static_cast<Edge*>(this)=
alpar@774
   798
	      Edge(typename Graph::InEdgeIt(*(gw->graph), n), true);
marci@775
   799
	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   800
		   !(*(gw->backward_filter))[*this]) 
marci@775
   801
	      *(static_cast<GraphEdge*>(this))=
marci@775
   802
		++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   803
	  }
alpar@774
   804
	} else {
alpar@774
   805
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   806
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   807
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   808
		 !(*(gw->backward_filter))[*this]) 
alpar@774
   809
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   810
	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@569
   811
	}
alpar@774
   812
	return *this;
marci@569
   813
      }
marci@569
   814
    };
marci@569
   815
alpar@774
   816
    class InEdgeIt : public Edge {
marci@650
   817
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   818
					ForwardFilterMap, BackwardFilterMap>;
marci@569
   819
    protected:
alpar@774
   820
      const SubBidirGraphWrapper<Graph, 
alpar@774
   821
				 ForwardFilterMap, BackwardFilterMap>* gw;
marci@569
   822
    public:
marci@569
   823
      InEdgeIt() { }
alpar@774
   824
      InEdgeIt(Invalid i) : Edge(i) { }
marci@569
   825
//the unique invalid iterator
marci@650
   826
      InEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   827
	       ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) : 
alpar@774
   828
	Edge(typename Graph::InEdgeIt(*(_gw.graph), n), false), gw(&_gw) { 
alpar@774
   829
	while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   830
	       !(*(gw->forward_filter))[*this]) 
alpar@774
   831
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   832
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   833
	if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   834
	  *static_cast<Edge*>(this)=
alpar@774
   835
	    Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), true);
marci@775
   836
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   837
		 !(*(gw->backward_filter))[*this]) 
marci@775
   838
	    *(static_cast<GraphEdge*>(this))=
marci@775
   839
	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   840
	}
alpar@774
   841
      }
alpar@774
   842
      InEdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   843
	       ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
alpar@774
   844
	Edge(e), gw(&_gw) { }
alpar@774
   845
      InEdgeIt& operator++() { 
alpar@774
   846
	if (!this->backward) {
marci@775
   847
	  Node n=gw->tail(*this);
alpar@774
   848
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   849
	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
alpar@774
   850
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   851
		 !(*(gw->forward_filter))[*this]) 
alpar@774
   852
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   853
	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
marci@775
   854
	  if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   855
	    *static_cast<Edge*>(this)=
alpar@774
   856
	      Edge(typename Graph::OutEdgeIt(*(gw->graph), n), true);
marci@775
   857
	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   858
		   !(*(gw->backward_filter))[*this]) 
marci@775
   859
	      *(static_cast<GraphEdge*>(this))=
marci@775
   860
		++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@775
   861
	  }
alpar@774
   862
	} else {
alpar@774
   863
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   864
	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
alpar@774
   865
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   866
		 !(*(gw->backward_filter))[*this]) 
alpar@774
   867
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   868
	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@569
   869
	}
alpar@774
   870
	return *this;
marci@569
   871
      }
marci@569
   872
    };
marci@569
   873
alpar@774
   874
    class EdgeIt : public Edge {
marci@650
   875
      friend class SubBidirGraphWrapper<Graph, 
marci@650
   876
					ForwardFilterMap, BackwardFilterMap>;
marci@569
   877
    protected:
alpar@774
   878
      const SubBidirGraphWrapper<Graph, 
alpar@774
   879
				 ForwardFilterMap, BackwardFilterMap>* gw;
marci@569
   880
    public:
marci@569
   881
      EdgeIt() { }
alpar@774
   882
      EdgeIt(Invalid i) : Edge(i) { }
alpar@774
   883
//the unique invalid iterator
marci@650
   884
      EdgeIt(const SubBidirGraphWrapper<Graph, 
marci@775
   885
	     ForwardFilterMap, BackwardFilterMap>& _gw) : 
marci@775
   886
	Edge(typename Graph::OutEdgeIt(*(_gw.graph)), false), gw(&_gw) { 
alpar@774
   887
	while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   888
	       !(*(gw->forward_filter))[*this]) 
alpar@774
   889
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   890
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   891
	if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   892
	  *static_cast<Edge*>(this)=
alpar@774
   893
	    Edge(typename Graph::EdgeIt(*(_gw.graph)), true);
marci@775
   894
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   895
		 !(*(gw->backward_filter))[*this]) 
marci@775
   896
	    *(static_cast<GraphEdge*>(this))=
marci@775
   897
	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   898
	}
alpar@774
   899
      }
alpar@774
   900
      EdgeIt(const SubBidirGraphWrapper<Graph, 
alpar@774
   901
	     ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
alpar@774
   902
	Edge(e), gw(&_gw) { }
alpar@774
   903
      EdgeIt& operator++() { 
alpar@774
   904
	if (!this->backward) {
alpar@774
   905
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   906
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
alpar@774
   907
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   908
		 !(*(gw->forward_filter))[*this]) 
alpar@774
   909
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   910
	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   911
	  if (*static_cast<GraphEdge*>(this)==INVALID) {
alpar@774
   912
	    *static_cast<Edge*>(this)=
alpar@774
   913
	      Edge(typename Graph::EdgeIt(*(gw->graph)), true);
marci@775
   914
	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
marci@775
   915
		   !(*(gw->backward_filter))[*this]) 
marci@775
   916
	      *(static_cast<GraphEdge*>(this))=
marci@775
   917
		++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@775
   918
	  }
alpar@774
   919
	} else {
alpar@774
   920
	  *(static_cast<GraphEdge*>(this))=
alpar@774
   921
	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
alpar@774
   922
	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
alpar@774
   923
		 !(*(gw->backward_filter))[*this]) 
alpar@774
   924
	    *(static_cast<GraphEdge*>(this))=
alpar@774
   925
	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
marci@569
   926
	}
alpar@774
   927
	return *this;
marci@569
   928
      }
marci@569
   929
    };
marci@569
   930
marci@569
   931
    using GraphWrapper<Graph>::first;
marci@569
   932
//     NodeIt& first(NodeIt& i) const { 
marci@569
   933
//       i=NodeIt(*this); return i;
marci@569
   934
//     }
marci@569
   935
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@569
   936
      i=OutEdgeIt(*this, p); return i;
marci@569
   937
    }
marci@569
   938
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@569
   939
      i=InEdgeIt(*this, p); return i;
marci@569
   940
    }
marci@569
   941
    EdgeIt& first(EdgeIt& i) const { 
marci@569
   942
      i=EdgeIt(*this); return i;
marci@569
   943
    }
marci@556
   944
  
alpar@774
   945
//     using GraphWrapper<Graph>::next;
alpar@774
   946
// //    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
alpar@774
   947
//     OutEdgeIt& next(OutEdgeIt& e) const { 
alpar@774
   948
//       if (!e.backward) {
alpar@774
   949
// 	Node v=this->graph->aNode(e.out);
alpar@774
   950
// 	this->graph->next(e.out);
alpar@774
   951
// 	while(this->graph->valid(e.out) && !(*forward_filter)[e]) { 
alpar@774
   952
// 	  this->graph->next(e.out); }
alpar@774
   953
// 	if (!this->graph->valid(e.out)) {
alpar@774
   954
// 	  e.backward=true;
alpar@774
   955
// 	  this->graph->first(e.in, v); 
alpar@774
   956
// 	  while(this->graph->valid(e.in) && !(*backward_filter)[e]) { 
alpar@774
   957
// 	    this->graph->next(e.in); }
alpar@774
   958
// 	}
alpar@774
   959
//       } else {
alpar@774
   960
// 	this->graph->next(e.in);
alpar@774
   961
// 	while(this->graph->valid(e.in) && !(*backward_filter)[e]) { 
alpar@774
   962
// 	  this->graph->next(e.in); } 
alpar@774
   963
//       }
alpar@774
   964
//       return e;
alpar@774
   965
//     }
alpar@774
   966
// //     FIXME Not tested
alpar@774
   967
//     InEdgeIt& next(InEdgeIt& e) const { 
alpar@774
   968
//       if (!e.backward) {
alpar@774
   969
// 	Node v=this->graph->aNode(e.in);
alpar@774
   970
// 	this->graph->next(e.in);
alpar@774
   971
// 	while(this->graph->valid(e.in) && !(*forward_filter)[e]) { 
alpar@774
   972
// 	  this->graph->next(e.in); }
alpar@774
   973
// 	if (!this->graph->valid(e.in)) {
alpar@774
   974
// 	  e.backward=true;
alpar@774
   975
// 	  this->graph->first(e.out, v); 
alpar@774
   976
// 	  while(this->graph->valid(e.out) && !(*backward_filter)[e]) { 
alpar@774
   977
// 	    this->graph->next(e.out); }
alpar@774
   978
// 	}
alpar@774
   979
//       } else {
alpar@774
   980
// 	this->graph->next(e.out);
alpar@774
   981
// 	while(this->graph->valid(e.out) && !(*backward_filter)[e]) { 
alpar@774
   982
// 	  this->graph->next(e.out); } 
alpar@774
   983
//       }
alpar@774
   984
//       return e;
alpar@774
   985
//     }
alpar@774
   986
//     EdgeIt& next(EdgeIt& e) const {
alpar@774
   987
//       if (!e.backward) {
alpar@774
   988
// 	this->graph->next(e.e);
alpar@774
   989
// 	while(this->graph->valid(e.e) && !(*forward_filter)[e]) { 
alpar@774
   990
// 	  this->graph->next(e.e); }
alpar@774
   991
// 	if (!this->graph->valid(e.e)) {
alpar@774
   992
// 	  e.backward=true;
alpar@774
   993
// 	  this->graph->first(e.e); 
alpar@774
   994
// 	  while(this->graph->valid(e.e) && !(*backward_filter)[e]) { 
alpar@774
   995
// 	    this->graph->next(e.e); }
alpar@774
   996
// 	}
alpar@774
   997
//       } else {
alpar@774
   998
// 	this->graph->next(e.e);
alpar@774
   999
// 	while(this->graph->valid(e.e) && !(*backward_filter)[e]) { 
alpar@774
  1000
// 	  this->graph->next(e.e); } 
alpar@774
  1001
//       }
alpar@774
  1002
//       return e;
alpar@774
  1003
//     }
marci@569
  1004
marci@569
  1005
    Node tail(Edge e) const { 
marci@569
  1006
      return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@569
  1007
    Node head(Edge e) const { 
marci@569
  1008
      return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@569
  1009
alpar@774
  1010
//     Node aNode(OutEdgeIt e) const { 
alpar@774
  1011
//       return ((!e.backward) ? this->graph->aNode(e.out) : 
alpar@774
  1012
// 	      this->graph->aNode(e.in)); }
alpar@774
  1013
//     Node bNode(OutEdgeIt e) const { 
alpar@774
  1014
//       return ((!e.backward) ? this->graph->bNode(e.out) : 
alpar@774
  1015
// 	      this->graph->bNode(e.in)); }
marci@569
  1016
alpar@774
  1017
//     Node aNode(InEdgeIt e) const { 
alpar@774
  1018
//       return ((!e.backward) ? this->graph->aNode(e.in) : 
alpar@774
  1019
// 	      this->graph->aNode(e.out)); }
alpar@774
  1020
//     Node bNode(InEdgeIt e) const { 
alpar@774
  1021
//       return ((!e.backward) ? this->graph->bNode(e.in) : 
alpar@774
  1022
// 	      this->graph->bNode(e.out)); }
marci@569
  1023
marci@572
  1024
    /// Gives back the opposite edge.
marci@572
  1025
    Edge opposite(const Edge& e) const { 
marci@572
  1026
      Edge f=e;
marci@572
  1027
      f.backward=!f.backward;
marci@572
  1028
      return f;
marci@572
  1029
    }
marci@572
  1030
marci@792
  1031
    /// \warning This is a linear time operation and works only if 
marci@792
  1032
    /// \c Graph::EdgeIt is defined.
marci@792
  1033
    int edgeNum() const { 
marci@792
  1034
      int i=0;
marci@792
  1035
      for (EdgeIt e(*this); e!=INVALID; ++e) ++i;
marci@792
  1036
      return i; 
marci@792
  1037
    }
marci@569
  1038
marci@569
  1039
    bool forward(const Edge& e) const { return !e.backward; }
marci@569
  1040
    bool backward(const Edge& e) const { return e.backward; }
marci@569
  1041
marci@569
  1042
marci@569
  1043
    template <typename T>
marci@792
  1044
    /// \c SubBidirGraphWrapper<..., ..., ...>::EdgeMap contains two 
marci@792
  1045
    /// Graph::EdgeMap one for the forward edges and 
marci@792
  1046
    /// one for the backward edges.
marci@569
  1047
    class EdgeMap {
marci@569
  1048
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@569
  1049
    public:
marci@623
  1050
      typedef T ValueType;
marci@623
  1051
      typedef Edge KeyType;
marci@650
  1052
      EdgeMap(const SubBidirGraphWrapper<Graph, 
alpar@774
  1053
	      ForwardFilterMap, BackwardFilterMap>& g) : 
alpar@774
  1054
	forward_map(*(g.graph)), backward_map(*(g.graph)) { }
marci@650
  1055
      EdgeMap(const SubBidirGraphWrapper<Graph, 
alpar@774
  1056
	      ForwardFilterMap, BackwardFilterMap>& g, T a) : 
alpar@774
  1057
	forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
marci@569
  1058
      void set(Edge e, T a) { 
marci@569
  1059
	if (!e.backward) 
marci@792
  1060
	  forward_map.set(e, a); 
marci@569
  1061
	else 
marci@792
  1062
	  backward_map.set(e, a); 
marci@569
  1063
      }
marci@569
  1064
      T operator[](Edge e) const { 
marci@569
  1065
	if (!e.backward) 
marci@792
  1066
	  return forward_map[e]; 
marci@569
  1067
	else 
marci@792
  1068
	  return backward_map[e]; 
marci@569
  1069
      }
marci@625
  1070
      void update() { 
marci@625
  1071
	forward_map.update(); 
marci@625
  1072
	backward_map.update();
marci@625
  1073
      }
marci@569
  1074
//       T get(Edge e) const { 
marci@569
  1075
// 	if (e.out_or_in) 
marci@569
  1076
// 	  return forward_map.get(e.out); 
marci@569
  1077
// 	else 
marci@569
  1078
// 	  return backward_map.get(e.in); 
marci@569
  1079
//       }
marci@569
  1080
    };
marci@569
  1081
  };
marci@569
  1082
marci@650
  1083
marci@650
  1084
  ///\brief A wrapper for composing bidirected graph from a directed one. 
marci@650
  1085
  ///
marci@650
  1086
  /// A wrapper for composing bidirected graph from a directed one. 
marci@650
  1087
  /// A bidirected graph is composed over the directed one without physical 
marci@650
  1088
  /// storage. As the oppositely directed edges are logically different ones 
marci@650
  1089
  /// the maps are able to attach different values for them.
marci@650
  1090
  template<typename Graph>
marci@650
  1091
  class BidirGraphWrapper : 
marci@650
  1092
    public SubBidirGraphWrapper<
marci@650
  1093
    Graph, 
marci@650
  1094
    ConstMap<typename Graph::Edge, bool>, 
marci@650
  1095
    ConstMap<typename Graph::Edge, bool> > {
marci@650
  1096
  public:
marci@650
  1097
    typedef  SubBidirGraphWrapper<
marci@650
  1098
      Graph, 
marci@650
  1099
      ConstMap<typename Graph::Edge, bool>, 
marci@650
  1100
      ConstMap<typename Graph::Edge, bool> > Parent; 
marci@650
  1101
  protected:
marci@650
  1102
    ConstMap<typename Graph::Edge, bool> cm;
marci@650
  1103
marci@655
  1104
    BidirGraphWrapper() : Parent(), cm(true) { 
marci@655
  1105
      Parent::setForwardFilterMap(cm);
marci@655
  1106
      Parent::setBackwardFilterMap(cm);
marci@655
  1107
    }
marci@650
  1108
  public:
marci@650
  1109
    BidirGraphWrapper(Graph& _graph) : Parent() { 
marci@650
  1110
      Parent::setGraph(_graph);
marci@650
  1111
      Parent::setForwardFilterMap(cm);
marci@650
  1112
      Parent::setBackwardFilterMap(cm);
marci@650
  1113
    }
marci@738
  1114
marci@738
  1115
    int edgeNum() const { 
marci@738
  1116
      return 2*this->graph->edgeNum();
marci@738
  1117
    }
marci@650
  1118
  };
marci@650
  1119
marci@650
  1120
marci@650
  1121
marci@792
  1122
  // this is a direct implementation of the bidirected-graph wrapper. 
marci@792
  1123
  // in early hugo, it was implemented that way.
marci@653
  1124
  template<typename Graph>
marci@653
  1125
  class OldBidirGraphWrapper : public GraphWrapper<Graph> {
marci@653
  1126
  public:
marci@653
  1127
    typedef GraphWrapper<Graph> Parent; 
marci@653
  1128
  protected:
marci@792
  1129
    OldBidirGraphWrapper() : GraphWrapper<Graph>() { }
marci@650
  1130
marci@653
  1131
  public:
marci@650
  1132
marci@792
  1133
    OldBidirGraphWrapper(Graph& _graph) : 
marci@792
  1134
      GraphWrapper<Graph>(_graph) { }
marci@650
  1135
marci@653
  1136
    class Edge; 
marci@653
  1137
    class OutEdgeIt; 
marci@653
  1138
    friend class Edge; 
marci@653
  1139
    friend class OutEdgeIt; 
marci@650
  1140
marci@653
  1141
    //template<typename T> class NodeMap;    
marci@653
  1142
    template<typename T> class EdgeMap;
marci@653
  1143
marci@653
  1144
    typedef typename GraphWrapper<Graph>::Node Node;
marci@653
  1145
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@653
  1146
marci@653
  1147
    class Edge : public Graph::Edge {
marci@653
  1148
      friend class OldBidirGraphWrapper<Graph>;
marci@653
  1149
      ///\bug ez nem is kell
marci@653
  1150
      //template<typename T> friend class NodeMap;
marci@653
  1151
      template<typename T> friend class EdgeMap;
marci@653
  1152
    protected:
marci@653
  1153
      bool backward; //true, iff backward
marci@653
  1154
//      typename Graph::Edge e;
marci@653
  1155
    public:
marci@653
  1156
      Edge() { }
marci@653
  1157
      ///\bug =false kell-e? zsoltnak kell az addEdge miatt
marci@653
  1158
      Edge(const typename Graph::Edge& _e, bool _backward=false) : 
marci@653
  1159
	Graph::Edge(_e), backward(_backward) { }
marci@653
  1160
      Edge(const Invalid& i) : Graph::Edge(i), backward(true) { }
marci@653
  1161
//the unique invalid iterator
marci@653
  1162
      friend bool operator==(const Edge& u, const Edge& v) { 
marci@653
  1163
	return (v.backward==u.backward && 
marci@653
  1164
		static_cast<typename Graph::Edge>(u)==
marci@653
  1165
		static_cast<typename Graph::Edge>(v));
marci@653
  1166
      } 
marci@653
  1167
      friend bool operator!=(const Edge& u, const Edge& v) { 
marci@653
  1168
	return (v.backward!=u.backward || 
marci@653
  1169
		static_cast<typename Graph::Edge>(u)!=
marci@653
  1170
		static_cast<typename Graph::Edge>(v));
marci@653
  1171
      } 
marci@653
  1172
    };
marci@653
  1173
marci@653
  1174
    class OutEdgeIt {
marci@653
  1175
      friend class OldBidirGraphWrapper<Graph>;
marci@653
  1176
    protected:
marci@653
  1177
      typename Graph::OutEdgeIt out;
marci@653
  1178
      typename Graph::InEdgeIt in;
marci@653
  1179
      bool backward;
marci@653
  1180
    public:
marci@653
  1181
      OutEdgeIt() { }
marci@653
  1182
      //FIXME
marci@653
  1183
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@653
  1184
      OutEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
marci@653
  1185
//the unique invalid iterator
marci@653
  1186
      OutEdgeIt(const OldBidirGraphWrapper<Graph>& _G, Node v) { 
marci@653
  1187
	backward=false;
marci@653
  1188
	_G.graph->first(out, v);
marci@653
  1189
	while(_G.graph->valid(out) && !_G.enabled(*this)) { _G.graph->next(out); }
marci@653
  1190
	if (!_G.graph->valid(out)) {
marci@653
  1191
	  backward=true;
marci@653
  1192
	  _G.graph->first(in, v);
marci@653
  1193
	  while(_G.graph->valid(in) && !_G.enabled(*this)) { _G.graph->next(in); }
marci@653
  1194
	}
marci@653
  1195
      }
marci@653
  1196
      operator Edge() const { 
marci@653
  1197
//	Edge e;
marci@653
  1198
//	e.forward=this->forward;
marci@653
  1199
//	if (this->forward) e=out; else e=in;
marci@653
  1200
//	return e;
marci@653
  1201
	if (this->backward) 
marci@653
  1202
	  return Edge(in, this->backward); 
marci@653
  1203
	else 
marci@653
  1204
	  return Edge(out, this->backward);
marci@653
  1205
      }
marci@653
  1206
    };
marci@653
  1207
marci@653
  1208
    class InEdgeIt {
marci@653
  1209
      friend class OldBidirGraphWrapper<Graph>;
marci@653
  1210
    protected:
marci@653
  1211
      typename Graph::OutEdgeIt out;
marci@653
  1212
      typename Graph::InEdgeIt in;
marci@653
  1213
      bool backward;
marci@653
  1214
    public:
marci@653
  1215
      InEdgeIt() { }
marci@653
  1216
      //FIXME
marci@653
  1217
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@653
  1218
      InEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
marci@653
  1219
//the unique invalid iterator
marci@653
  1220
      InEdgeIt(const OldBidirGraphWrapper<Graph>& _G, Node v) { 
marci@653
  1221
	backward=false;
marci@653
  1222
	_G.graph->first(in, v);
marci@653
  1223
	while(_G.graph->valid(in) && !_G.enabled(*this)) { _G.graph->next(in); }
marci@653
  1224
	if (!_G.graph->valid(in)) {
marci@653
  1225
	  backward=true;
marci@653
  1226
	  _G.graph->first(out, v);
marci@653
  1227
	  while(_G.graph->valid(out) && !_G.enabled(*this)) { _G.graph->next(out); }
marci@653
  1228
	}
marci@653
  1229
      }
marci@653
  1230
      operator Edge() const { 
marci@653
  1231
//	Edge e;
marci@653
  1232
//	e.forward=this->forward;
marci@653
  1233
//	if (this->forward) e=out; else e=in;
marci@653
  1234
//	return e;
marci@653
  1235
	if (this->backward) 
marci@653
  1236
	  return Edge(out, this->backward); 
marci@653
  1237
	else 
marci@653
  1238
	  return Edge(in, this->backward);
marci@653
  1239
      }
marci@653
  1240
    };
marci@653
  1241
marci@653
  1242
    class EdgeIt {
marci@653
  1243
      friend class OldBidirGraphWrapper<Graph>;
marci@653
  1244
    protected:
marci@653
  1245
      typename Graph::EdgeIt e;
marci@653
  1246
      bool backward;
marci@653
  1247
    public:
marci@653
  1248
      EdgeIt() { }
marci@653
  1249
      EdgeIt(const Invalid& i) : e(i), backward(true) { }
marci@653
  1250
      EdgeIt(const OldBidirGraphWrapper<Graph>& _G) { 
marci@653
  1251
	backward=false;
marci@653
  1252
	_G.graph->first(e);
marci@653
  1253
	while (_G.graph->valid(e) && !_G.enabled(*this)) _G.graph->next(e);
marci@653
  1254
	if (!_G.graph->valid(e)) {
marci@653
  1255
	  backward=true;
marci@653
  1256
	  _G.graph->first(e);
marci@653
  1257
	  while (_G.graph->valid(e) && !_G.enabled(*this)) _G.graph->next(e);
marci@653
  1258
	}
marci@653
  1259
      }
marci@653
  1260
      operator Edge() const { 
marci@653
  1261
	return Edge(e, this->backward);
marci@653
  1262
      }
marci@653
  1263
    };
marci@653
  1264
marci@653
  1265
    using GraphWrapper<Graph>::first;
marci@653
  1266
//     NodeIt& first(NodeIt& i) const { 
marci@653
  1267
//       i=NodeIt(*this); return i;
marci@653
  1268
//     }
marci@653
  1269
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@653
  1270
      i=OutEdgeIt(*this, p); return i;
marci@653
  1271
    }
marci@653
  1272
//    FIXME not tested
marci@653
  1273
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@653
  1274
      i=InEdgeIt(*this, p); return i;
marci@653
  1275
    }
marci@653
  1276
    EdgeIt& first(EdgeIt& i) const { 
marci@653
  1277
      i=EdgeIt(*this); return i;
marci@653
  1278
    }
marci@653
  1279
  
marci@653
  1280
    using GraphWrapper<Graph>::next;
marci@653
  1281
//    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@653
  1282
    OutEdgeIt& next(OutEdgeIt& e) const { 
marci@653
  1283
      if (!e.backward) {
marci@653
  1284
	Node v=this->graph->aNode(e.out);
marci@653
  1285
	this->graph->next(e.out);
marci@653
  1286
	while(this->graph->valid(e.out) && !enabled(e)) { 
marci@653
  1287
	  this->graph->next(e.out); }
marci@653
  1288
	if (!this->graph->valid(e.out)) {
marci@653
  1289
	  e.backward=true;
marci@653
  1290
	  this->graph->first(e.in, v); 
marci@653
  1291
	  while(this->graph->valid(e.in) && !enabled(e)) { 
marci@653
  1292
	    this->graph->next(e.in); }
marci@653
  1293
	}
marci@653
  1294
      } else {
marci@653
  1295
	this->graph->next(e.in);
marci@653
  1296
	while(this->graph->valid(e.in) && !enabled(e)) { 
marci@653
  1297
	  this->graph->next(e.in); } 
marci@653
  1298
      }
marci@653
  1299
      return e;
marci@653
  1300
    }
marci@653
  1301
//     FIXME Not tested
marci@653
  1302
    InEdgeIt& next(InEdgeIt& e) const { 
marci@653
  1303
      if (!e.backward) {
marci@653
  1304
	Node v=this->graph->aNode(e.in);
marci@653
  1305
	this->graph->next(e.in);
marci@653
  1306
	while(this->graph->valid(e.in) && !enabled(e)) { 
marci@653
  1307
	  this->graph->next(e.in); }
marci@653
  1308
	if (!this->graph->valid(e.in)) {
marci@653
  1309
	  e.backward=true;
marci@653
  1310
	  this->graph->first(e.out, v); 
marci@653
  1311
	  while(this->graph->valid(e.out) && !enabled(e)) { 
marci@653
  1312
	    this->graph->next(e.out); }
marci@653
  1313
	}
marci@653
  1314
      } else {
marci@653
  1315
	this->graph->next(e.out);
marci@653
  1316
	while(this->graph->valid(e.out) && !enabled(e)) { 
marci@653
  1317
	  this->graph->next(e.out); } 
marci@653
  1318
      }
marci@653
  1319
      return e;
marci@653
  1320
    }
marci@653
  1321
    EdgeIt& next(EdgeIt& e) const {
marci@653
  1322
      if (!e.backward) {
marci@653
  1323
	this->graph->next(e.e);
marci@653
  1324
	while(this->graph->valid(e.e) && !enabled(e)) { 
marci@653
  1325
	  this->graph->next(e.e); }
marci@653
  1326
	if (!this->graph->valid(e.e)) {
marci@653
  1327
	  e.backward=true;
marci@653
  1328
	  this->graph->first(e.e); 
marci@653
  1329
	  while(this->graph->valid(e.e) && !enabled(e)) { 
marci@653
  1330
	    this->graph->next(e.e); }
marci@653
  1331
	}
marci@653
  1332
      } else {
marci@653
  1333
	this->graph->next(e.e);
marci@653
  1334
	while(this->graph->valid(e.e) && !enabled(e)) { 
marci@653
  1335
	  this->graph->next(e.e); } 
marci@653
  1336
      }
marci@653
  1337
      return e;
marci@653
  1338
    }
marci@653
  1339
marci@653
  1340
    Node tail(Edge e) const { 
marci@653
  1341
      return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@653
  1342
    Node head(Edge e) const { 
marci@653
  1343
      return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@653
  1344
marci@653
  1345
    Node aNode(OutEdgeIt e) const { 
marci@653
  1346
      return ((!e.backward) ? this->graph->aNode(e.out) : 
marci@653
  1347
	      this->graph->aNode(e.in)); }
marci@653
  1348
    Node bNode(OutEdgeIt e) const { 
marci@653
  1349
      return ((!e.backward) ? this->graph->bNode(e.out) : 
marci@653
  1350
	      this->graph->bNode(e.in)); }
marci@653
  1351
marci@653
  1352
    Node aNode(InEdgeIt e) const { 
marci@653
  1353
      return ((!e.backward) ? this->graph->aNode(e.in) : 
marci@653
  1354
	      this->graph->aNode(e.out)); }
marci@653
  1355
    Node bNode(InEdgeIt e) const { 
marci@653
  1356
      return ((!e.backward) ? this->graph->bNode(e.in) : 
marci@653
  1357
	      this->graph->bNode(e.out)); }
marci@653
  1358
marci@653
  1359
    /// Gives back the opposite edge.
marci@653
  1360
    Edge opposite(const Edge& e) const { 
marci@653
  1361
      Edge f=e;
marci@653
  1362
      f.backward=!f.backward;
marci@653
  1363
      return f;
marci@653
  1364
    }
marci@653
  1365
marci@653
  1366
//    int nodeNum() const { return graph->nodeNum(); }
marci@653
  1367
    //FIXME
marci@653
  1368
    void edgeNum() const { }
marci@653
  1369
    //int edgeNum() const { return graph->edgeNum(); }
marci@653
  1370
marci@653
  1371
marci@653
  1372
//    int id(Node v) const { return graph->id(v); }
marci@653
  1373
marci@653
  1374
    bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@653
  1375
    bool valid(Edge e) const { 
marci@653
  1376
      return this->graph->valid(e);
marci@653
  1377
	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@653
  1378
    }
marci@653
  1379
marci@653
  1380
    bool forward(const Edge& e) const { return !e.backward; }
marci@653
  1381
    bool backward(const Edge& e) const { return e.backward; }
marci@653
  1382
marci@653
  1383
    bool enabled(const Edge& e) const { 
marci@653
  1384
      if (!e.backward) 
marci@653
  1385
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@653
  1386
	//return ((*capacity)[e]-(*flow)[e]);
marci@653
  1387
	return true;
marci@653
  1388
      else 
marci@653
  1389
//	return (flow->get(e.in)); 
marci@653
  1390
	//return ((*flow)[e]); 
marci@653
  1391
	return true;
marci@653
  1392
    }
marci@650
  1393
marci@653
  1394
//     Number enabled(typename Graph::OutEdgeIt out) const { 
marci@653
  1395
// //      return (capacity->get(out)-flow->get(out)); 
marci@653
  1396
//       return ((*capacity)[out]-(*flow)[out]); 
marci@653
  1397
//     }
marci@653
  1398
    
marci@653
  1399
//     Number enabled(typename Graph::InEdgeIt in) const { 
marci@653
  1400
// //      return (flow->get(in)); 
marci@653
  1401
//       return ((*flow)[in]); 
marci@650
  1402
//     }
marci@650
  1403
marci@653
  1404
    template <typename T>
marci@653
  1405
    class EdgeMap {
marci@653
  1406
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@653
  1407
    public:
marci@653
  1408
      typedef T ValueType;
marci@653
  1409
      typedef Edge KeyType;
marci@653
  1410
      EdgeMap(const OldBidirGraphWrapper<Graph>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@653
  1411
      EdgeMap(const OldBidirGraphWrapper<Graph>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@653
  1412
      void set(Edge e, T a) { 
marci@653
  1413
	if (!e.backward) 
marci@653
  1414
	  forward_map.set(e/*.out*/, a); 
marci@653
  1415
	else 
marci@653
  1416
	  backward_map.set(e/*.in*/, a); 
marci@653
  1417
      }
marci@653
  1418
      T operator[](Edge e) const { 
marci@653
  1419
	if (!e.backward) 
marci@653
  1420
	  return forward_map[e/*.out*/]; 
marci@653
  1421
	else 
marci@653
  1422
	  return backward_map[e/*.in*/]; 
marci@653
  1423
      }
marci@653
  1424
      void update() { 
marci@653
  1425
	forward_map.update(); 
marci@653
  1426
	backward_map.update();
marci@653
  1427
      }
marci@653
  1428
//       T get(Edge e) const { 
marci@653
  1429
// 	if (e.out_or_in) 
marci@653
  1430
// 	  return forward_map.get(e.out); 
marci@653
  1431
// 	else 
marci@653
  1432
// 	  return backward_map.get(e.in); 
marci@653
  1433
//       }
marci@653
  1434
    };
marci@653
  1435
  };
marci@650
  1436
marci@650
  1437
marci@650
  1438
marci@612
  1439
  /// \brief A bidirected graph template.
marci@612
  1440
  ///
marci@612
  1441
  /// A bidirected graph template.
marci@612
  1442
  /// Such a bidirected graph stores each pair of oppositely directed edges 
marci@612
  1443
  /// ones in the memory, i.e. a directed graph of type 
marci@612
  1444
  /// \c Graph is used for that.
marci@612
  1445
  /// As the oppositely directed edges are logically different ones 
marci@612
  1446
  /// the maps are able to attach different values for them.
marci@612
  1447
  /// \ingroup graphs
marci@612
  1448
  template<typename Graph>
marci@612
  1449
  class BidirGraph : public BidirGraphWrapper<Graph> {
marci@650
  1450
  public:
marci@612
  1451
    typedef UndirGraphWrapper<Graph> Parent;
marci@612
  1452
  protected:
marci@612
  1453
    Graph gr;
marci@612
  1454
  public:
marci@612
  1455
    BidirGraph() : BidirGraphWrapper<Graph>() { 
marci@612
  1456
      Parent::setGraph(gr); 
marci@612
  1457
    }
marci@612
  1458
  };
marci@569
  1459
marci@556
  1460
marci@650
  1461
marci@650
  1462
  template<typename Graph, typename Number,
marci@650
  1463
	   typename CapacityMap, typename FlowMap>
marci@658
  1464
  class ResForwardFilter {
marci@658
  1465
    //    const Graph* graph;
marci@650
  1466
    const CapacityMap* capacity;
marci@650
  1467
    const FlowMap* flow;
marci@650
  1468
  public:
marci@658
  1469
    ResForwardFilter(/*const Graph& _graph, */
marci@658
  1470
		     const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1471
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1472
    ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@658
  1473
    //void setGraph(const Graph& _graph) { graph=&_graph; }
marci@656
  1474
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1475
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1476
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1477
      return (Number((*flow)[e]) < Number((*capacity)[e]));
marci@650
  1478
    }
marci@650
  1479
  };
marci@650
  1480
marci@650
  1481
  template<typename Graph, typename Number,
marci@650
  1482
	   typename CapacityMap, typename FlowMap>
marci@658
  1483
  class ResBackwardFilter {
marci@658
  1484
    //const Graph* graph;
marci@650
  1485
    const CapacityMap* capacity;
marci@650
  1486
    const FlowMap* flow;
marci@650
  1487
  public:
marci@658
  1488
    ResBackwardFilter(/*const Graph& _graph,*/ 
marci@658
  1489
		      const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1490
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1491
    ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@658
  1492
    //void setGraph(const Graph& _graph) { graph=&_graph; }
marci@656
  1493
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1494
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1495
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1496
      return (Number(0) < Number((*flow)[e]));
marci@650
  1497
    }
marci@650
  1498
  };
marci@650
  1499
marci@653
  1500
  
marci@653
  1501
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@650
  1502
marci@653
  1503
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@650
  1504
  template<typename Graph, typename Number, 
marci@650
  1505
	   typename CapacityMap, typename FlowMap>
marci@653
  1506
  class ResGraphWrapper : 
marci@650
  1507
    public SubBidirGraphWrapper< 
marci@650
  1508
    Graph, 
marci@658
  1509
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1510
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
marci@650
  1511
  public:
marci@650
  1512
    typedef SubBidirGraphWrapper< 
marci@650
  1513
      Graph, 
marci@658
  1514
      ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1515
      ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
marci@650
  1516
  protected:
marci@650
  1517
    const CapacityMap* capacity;
marci@650
  1518
    FlowMap* flow;
marci@658
  1519
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
marci@658
  1520
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
marci@658
  1521
    ResGraphWrapper() : Parent(), 
marci@658
  1522
 			capacity(0), flow(0) { }
marci@658
  1523
    void setCapacityMap(const CapacityMap& _capacity) {
marci@658
  1524
      capacity=&_capacity;
marci@658
  1525
      forward_filter.setCapacity(_capacity);
marci@658
  1526
      backward_filter.setCapacity(_capacity);
marci@658
  1527
    }
marci@658
  1528
    void setFlowMap(FlowMap& _flow) {
marci@658
  1529
      flow=&_flow;
marci@658
  1530
      forward_filter.setFlow(_flow);
marci@658
  1531
      backward_filter.setFlow(_flow);
marci@658
  1532
    }
marci@658
  1533
//     /// \bug does graph reference needed in filtermaps??
marci@658
  1534
//     void setGraph(const Graph& _graph) { 
marci@658
  1535
//       Parent::setGraph(_graph);
marci@658
  1536
//       forward_filter.setGraph(_graph);
marci@658
  1537
//       backward_filter.setGraph(_graph);
marci@656
  1538
//     }
marci@650
  1539
  public:
marci@653
  1540
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@650
  1541
		       FlowMap& _flow) : 
marci@650
  1542
      Parent(), capacity(&_capacity), flow(&_flow), 
marci@658
  1543
      forward_filter(/*_graph,*/ _capacity, _flow), 
marci@658
  1544
      backward_filter(/*_graph,*/ _capacity, _flow) {
marci@650
  1545
      Parent::setGraph(_graph);
marci@650
  1546
      Parent::setForwardFilterMap(forward_filter);
marci@650
  1547
      Parent::setBackwardFilterMap(backward_filter);
marci@650
  1548
    }
marci@650
  1549
marci@660
  1550
    typedef typename Parent::Edge Edge;
marci@660
  1551
marci@650
  1552
    //    bool forward(const Parent::Edge& e) const { return Parent::forward(e); }
marci@650
  1553
    //bool backward(const Edge& e) const { return e.backward; }
marci@650
  1554
marci@660
  1555
    void augment(const Edge& e, Number a) const {
marci@650
  1556
      if (Parent::forward(e))  
marci@650
  1557
// 	flow->set(e.out, flow->get(e.out)+a);
marci@650
  1558
	flow->set(e, (*flow)[e]+a);
marci@650
  1559
      else  
marci@650
  1560
	//flow->set(e.in, flow->get(e.in)-a);
marci@650
  1561
	flow->set(e, (*flow)[e]-a);
marci@650
  1562
    }
marci@650
  1563
marci@660
  1564
    /// \deprecated
marci@660
  1565
    ///
marci@660
  1566
    Number resCap(const Edge& e) const { 
marci@650
  1567
      if (Parent::forward(e)) 
marci@650
  1568
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@650
  1569
	return ((*capacity)[e]-(*flow)[e]); 
marci@650
  1570
      else 
marci@650
  1571
//	return (flow->get(e.in)); 
marci@650
  1572
	return ((*flow)[e]); 
marci@650
  1573
    }
marci@650
  1574
marci@660
  1575
    /// \brief Residual capacity map.
marci@660
  1576
    ///
marci@792
  1577
    /// In generic residual graphs the residual capacity can be obtained as a map. Not tested.
marci@660
  1578
    class ResCap {
marci@660
  1579
    protected:
marci@660
  1580
      const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>* res_graph;
marci@660
  1581
    public:
marci@660
  1582
      typedef Number ValueType;
marci@660
  1583
      typedef Edge KeyType;
marci@660
  1584
      ResCap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _res_graph) : 
marci@660
  1585
	res_graph(&_res_graph) { }
marci@660
  1586
      Number operator[](const Edge& e) const { 
marci@660
  1587
	if (res_graph->forward(e)) 
marci@660
  1588
	  //	return (capacity->get(e.out)-flow->get(e.out)); 
marci@660
  1589
	  return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; 
marci@660
  1590
	else 
marci@660
  1591
	  //	return (flow->get(e.in)); 
marci@660
  1592
	  return (*(res_graph->flow))[e]; 
marci@660
  1593
      }
marci@660
  1594
      /// \bug not needed with dynamic maps, or does it?
marci@660
  1595
      void update() { }
marci@660
  1596
    };
marci@660
  1597
marci@650
  1598
  };
marci@650
  1599
marci@650
  1600
marci@556
  1601
  template<typename Graph, typename Number, 
marci@556
  1602
	   typename CapacityMap, typename FlowMap>
marci@653
  1603
  class OldResGraphWrapper : public GraphWrapper<Graph> {
marci@650
  1604
  public:
marci@650
  1605
    typedef GraphWrapper<Graph> Parent; 
marci@556
  1606
  protected:
marci@556
  1607
    const CapacityMap* capacity;
marci@556
  1608
    FlowMap* flow;
marci@556
  1609
marci@653
  1610
    OldResGraphWrapper() : GraphWrapper<Graph>(0), 
marci@556
  1611
			capacity(0), flow(0) { }
marci@560
  1612
    void setCapacityMap(const CapacityMap& _capacity) {
marci@560
  1613
      capacity=&_capacity;
marci@556
  1614
    }
marci@556
  1615
    void setFlowMap(FlowMap& _flow) {
marci@556
  1616
      flow=&_flow;
marci@556
  1617
    }
marci@556
  1618
marci@556
  1619
  public:
marci@556
  1620
marci@653
  1621
    OldResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@556
  1622
		    FlowMap& _flow) : 
marci@556
  1623
      GraphWrapper<Graph>(_graph), capacity(&_capacity), flow(&_flow) { }
marci@556
  1624
marci@556
  1625
    class Edge; 
marci@556
  1626
    class OutEdgeIt; 
marci@556
  1627
    friend class Edge; 
marci@556
  1628
    friend class OutEdgeIt; 
marci@556
  1629
marci@556
  1630
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
  1631
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
  1632
    class Edge : public Graph::Edge {
marci@653
  1633
      friend class OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
  1634
    protected:
marci@565
  1635
      bool backward; //true, iff backward
marci@556
  1636
//      typename Graph::Edge e;
marci@556
  1637
    public:
marci@556
  1638
      Edge() { }
marci@565
  1639
      Edge(const typename Graph::Edge& _e, bool _backward) : 
marci@565
  1640
	Graph::Edge(_e), backward(_backward) { }
marci@565
  1641
      Edge(const Invalid& i) : Graph::Edge(i), backward(true) { }
marci@556
  1642
//the unique invalid iterator
marci@556
  1643
      friend bool operator==(const Edge& u, const Edge& v) { 
marci@565
  1644
	return (v.backward==u.backward && 
marci@556
  1645
		static_cast<typename Graph::Edge>(u)==
marci@556
  1646
		static_cast<typename Graph::Edge>(v));
marci@556
  1647
      } 
marci@556
  1648
      friend bool operator!=(const Edge& u, const Edge& v) { 
marci@565
  1649
	return (v.backward!=u.backward || 
marci@556
  1650
		static_cast<typename Graph::Edge>(u)!=
marci@556
  1651
		static_cast<typename Graph::Edge>(v));
marci@556
  1652
      } 
marci@556
  1653
    };
marci@556
  1654
marci@556
  1655
    class OutEdgeIt {
marci@653
  1656
      friend class OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
  1657
    protected:
marci@556
  1658
      typename Graph::OutEdgeIt out;
marci@556
  1659
      typename Graph::InEdgeIt in;
marci@565
  1660
      bool backward;
marci@556
  1661
    public:
marci@556
  1662
      OutEdgeIt() { }
marci@556
  1663
      //FIXME
marci@556
  1664
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@565
  1665
      OutEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
marci@556
  1666
//the unique invalid iterator
marci@653
  1667
      OutEdgeIt(const OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, Node v) { 
marci@565
  1668
	backward=false;
marci@569
  1669
	_G.graph->first(out, v);
marci@569
  1670
	while( _G.graph->valid(out) && !(_G.resCap(*this)>0) ) { _G.graph->next(out); }
marci@569
  1671
	if (!_G.graph->valid(out)) {
marci@565
  1672
	  backward=true;
marci@569
  1673
	  _G.graph->first(in, v);
marci@569
  1674
	  while( _G.graph->valid(in) && !(_G.resCap(*this)>0) ) { _G.graph->next(in); }
marci@556
  1675
	}
marci@556
  1676
      }
marci@556
  1677
      operator Edge() const { 
marci@556
  1678
//	Edge e;
marci@556
  1679
//	e.forward=this->forward;
marci@556
  1680
//	if (this->forward) e=out; else e=in;
marci@556
  1681
//	return e;
marci@565
  1682
	if (this->backward) 
marci@565
  1683
	  return Edge(in, this->backward); 
marci@556
  1684
	else 
marci@565
  1685
	  return Edge(out, this->backward);
marci@556
  1686
      }
marci@556
  1687
    };
marci@556
  1688
marci@556
  1689
    class InEdgeIt {
marci@653
  1690
      friend class OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
  1691
    protected:
marci@556
  1692
      typename Graph::OutEdgeIt out;
marci@556
  1693
      typename Graph::InEdgeIt in;
marci@565
  1694
      bool backward;
marci@556
  1695
    public:
marci@556
  1696
      InEdgeIt() { }
marci@556
  1697
      //FIXME
marci@556
  1698
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@565
  1699
      InEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
marci@556
  1700
//the unique invalid iterator
marci@653
  1701
      InEdgeIt(const OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, Node v) { 
marci@565
  1702
	backward=false;
marci@569
  1703
	_G.graph->first(in, v);
marci@569
  1704
	while( _G.graph->valid(in) && !(_G.resCap(*this)>0) ) { _G.graph->next(in); }
marci@569
  1705
	if (!_G.graph->valid(in)) {
marci@565
  1706
	  backward=true;
marci@569
  1707
	  _G.graph->first(out, v);
marci@569
  1708
	  while( _G.graph->valid(out) && !(_G.resCap(*this)>0) ) { _G.graph->next(out); }
marci@556
  1709
	}
marci@556
  1710
      }
marci@556
  1711
      operator Edge() const { 
marci@556
  1712
//	Edge e;
marci@556
  1713
//	e.forward=this->forward;
marci@556
  1714
//	if (this->forward) e=out; else e=in;
marci@556
  1715
//	return e;
marci@565
  1716
	if (this->backward) 
marci@565
  1717
	  return Edge(out, this->backward); 
marci@556
  1718
	else 
marci@565
  1719
	  return Edge(in, this->backward);
marci@556
  1720
      }
marci@556
  1721
    };
marci@556
  1722
marci@556
  1723
    class EdgeIt {
marci@653
  1724
      friend class OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
  1725
    protected:
marci@556
  1726
      typename Graph::EdgeIt e;
marci@565
  1727
      bool backward;
marci@556
  1728
    public:
marci@556
  1729
      EdgeIt() { }
marci@565
  1730
      EdgeIt(const Invalid& i) : e(i), backward(true) { }
marci@653
  1731
      EdgeIt(const OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) { 
marci@565
  1732
	backward=false;
marci@569
  1733
	_G.graph->first(e);
marci@569
  1734
	while (_G.graph->valid(e) && !(_G.resCap(*this)>0)) _G.graph->next(e);
marci@569
  1735
	if (!_G.graph->valid(e)) {
marci@565
  1736
	  backward=true;
marci@569
  1737
	  _G.graph->first(e);
marci@569
  1738
	  while (_G.graph->valid(e) && !(_G.resCap(*this)>0)) _G.graph->next(e);
marci@556
  1739
	}
marci@556
  1740
      }
marci@556
  1741
      operator Edge() const { 
marci@565
  1742
	return Edge(e, this->backward);
marci@556
  1743
      }
marci@556
  1744
    };
marci@556
  1745
marci@556
  1746
    using GraphWrapper<Graph>::first;
marci@556
  1747
//     NodeIt& first(NodeIt& i) const { 
marci@556
  1748
//       i=NodeIt(*this); return i;
marci@556
  1749
//     }
marci@556
  1750
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
  1751
      i=OutEdgeIt(*this, p); return i;
marci@556
  1752
    }
marci@556
  1753
//    FIXME not tested
marci@556
  1754
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
  1755
      i=InEdgeIt(*this, p); return i;
marci@556
  1756
    }
marci@556
  1757
    EdgeIt& first(EdgeIt& i) const { 
marci@556
  1758
      i=EdgeIt(*this); return i;
marci@556
  1759
    }
marci@556
  1760
  
marci@556
  1761
    using GraphWrapper<Graph>::next;
marci@556
  1762
//    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@556
  1763
    OutEdgeIt& next(OutEdgeIt& e) const { 
marci@565
  1764
      if (!e.backward) {
marci@556
  1765
	Node v=this->graph->aNode(e.out);
marci@556
  1766
	this->graph->next(e.out);
marci@556
  1767
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
  1768
	  this->graph->next(e.out); }
marci@556
  1769
	if (!this->graph->valid(e.out)) {
marci@565
  1770
	  e.backward=true;
marci@556
  1771
	  this->graph->first(e.in, v); 
marci@556
  1772
	  while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
  1773
	    this->graph->next(e.in); }
marci@556
  1774
	}
marci@556
  1775
      } else {
marci@556
  1776
	this->graph->next(e.in);
marci@556
  1777
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
  1778
	  this->graph->next(e.in); } 
marci@556
  1779
      }
marci@556
  1780
      return e;
marci@556
  1781
    }
marci@556
  1782
//     FIXME Not tested
marci@556
  1783
    InEdgeIt& next(InEdgeIt& e) const { 
marci@565
  1784
      if (!e.backward) {
marci@556
  1785
	Node v=this->graph->aNode(e.in);
marci@556
  1786
	this->graph->next(e.in);
marci@556
  1787
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
  1788
	  this->graph->next(e.in); }
marci@556
  1789
	if (!this->graph->valid(e.in)) {
marci@565
  1790
	  e.backward=true;
marci@556
  1791
	  this->graph->first(e.out, v); 
marci@556
  1792
	  while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
  1793
	    this->graph->next(e.out); }
marci@556
  1794
	}
marci@556
  1795
      } else {
marci@556
  1796
	this->graph->next(e.out);
marci@556
  1797
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
  1798
	  this->graph->next(e.out); } 
marci@556
  1799
      }
marci@556
  1800
      return e;
marci@556
  1801
    }
marci@556
  1802
    EdgeIt& next(EdgeIt& e) const {
marci@565
  1803
      if (!e.backward) {
marci@556
  1804
	this->graph->next(e.e);
marci@556
  1805
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
  1806
	  this->graph->next(e.e); }
marci@556
  1807
	if (!this->graph->valid(e.e)) {
marci@565
  1808
	  e.backward=true;
marci@556
  1809
	  this->graph->first(e.e); 
marci@556
  1810
	  while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
  1811
	    this->graph->next(e.e); }
marci@556
  1812
	}
marci@556
  1813
      } else {
marci@556
  1814
	this->graph->next(e.e);
marci@556
  1815
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
  1816
	  this->graph->next(e.e); } 
marci@556
  1817
      }
marci@556
  1818
      return e;
marci@556
  1819
    }
marci@556
  1820
marci@556
  1821
    Node tail(Edge e) const { 
marci@565
  1822
      return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@556
  1823
    Node head(Edge e) const { 
marci@565
  1824
      return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@556
  1825
marci@556
  1826
    Node aNode(OutEdgeIt e) const { 
marci@565
  1827
      return ((!e.backward) ? this->graph->aNode(e.out) : 
marci@556
  1828
	      this->graph->aNode(e.in)); }
marci@556
  1829
    Node bNode(OutEdgeIt e) const { 
marci@565
  1830
      return ((!e.backward) ? this->graph->bNode(e.out) : 
marci@556
  1831
	      this->graph->bNode(e.in)); }
marci@556
  1832
marci@556
  1833
    Node aNode(InEdgeIt e) const { 
marci@565
  1834
      return ((!e.backward) ? this->graph->aNode(e.in) : 
marci@556
  1835
	      this->graph->aNode(e.out)); }
marci@556
  1836
    Node bNode(InEdgeIt e) const { 
marci@565
  1837
      return ((!e.backward) ? this->graph->bNode(e.in) : 
marci@556
  1838
	      this->graph->bNode(e.out)); }
marci@556
  1839
marci@556
  1840
//    int nodeNum() const { return graph->nodeNum(); }
marci@556
  1841
    //FIXME
marci@556
  1842
    void edgeNum() const { }
marci@556
  1843
    //int edgeNum() const { return graph->edgeNum(); }
marci@556
  1844
marci@556
  1845
marci@556
  1846
//    int id(Node v) const { return graph->id(v); }
marci@556
  1847
marci@556
  1848
    bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@556
  1849
    bool valid(Edge e) const { 
marci@556
  1850
      return this->graph->valid(e);
marci@556
  1851
	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@556
  1852
    }
marci@556
  1853
marci@565
  1854
    bool forward(const Edge& e) const { return !e.backward; }
marci@565
  1855
    bool backward(const Edge& e) const { return e.backward; }
marci@556
  1856
marci@556
  1857
    void augment(const Edge& e, Number a) const {
marci@565
  1858
      if (!e.backward)  
marci@556
  1859
// 	flow->set(e.out, flow->get(e.out)+a);
marci@556
  1860
	flow->set(e, (*flow)[e]+a);
marci@556
  1861
      else  
marci@556
  1862
// 	flow->set(e.in, flow->get(e.in)-a);
marci@556
  1863
	flow->set(e, (*flow)[e]-a);
marci@556
  1864
    }
marci@556
  1865
marci@556
  1866
    Number resCap(const Edge& e) const { 
marci@565
  1867
      if (!e.backward) 
marci@556
  1868
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@556
  1869
	return ((*capacity)[e]-(*flow)[e]); 
marci@556
  1870
      else 
marci@556
  1871
//	return (flow->get(e.in)); 
marci@556
  1872
	return ((*flow)[e]); 
marci@556
  1873
    }
marci@556
  1874
marci@556
  1875
//     Number resCap(typename Graph::OutEdgeIt out) const { 
marci@556
  1876
// //      return (capacity->get(out)-flow->get(out)); 
marci@556
  1877
//       return ((*capacity)[out]-(*flow)[out]); 
marci@556
  1878
//     }
marci@556
  1879
    
marci@556
  1880
//     Number resCap(typename Graph::InEdgeIt in) const { 
marci@556
  1881
// //      return (flow->get(in)); 
marci@556
  1882
//       return ((*flow)[in]); 
marci@556
  1883
//     }
marci@556
  1884
marci@556
  1885
    template <typename T>
marci@556
  1886
    class EdgeMap {
marci@556
  1887
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@556
  1888
    public:
marci@624
  1889
      typedef T ValueType;
marci@624
  1890
      typedef Edge KeyType;
marci@653
  1891
      EdgeMap(const OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@653
  1892
      EdgeMap(const OldResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@556
  1893
      void set(Edge e, T a) { 
marci@565
  1894
	if (!e.backward) 
marci@624
  1895
	  forward_map.set(e/*.out*/, a); 
marci@556
  1896
	else 
marci@624
  1897
	  backward_map.set(e/*.in*/, a); 
marci@556
  1898
      }
marci@556
  1899
      T operator[](Edge e) const { 
marci@565
  1900
	if (!e.backward) 
marci@624
  1901
	  return forward_map[e/*.out*/]; 
marci@556
  1902
	else 
marci@624
  1903
	  return backward_map[e/*.in*/]; 
marci@556
  1904
      }
marci@625
  1905
      void update() { 
marci@625
  1906
	forward_map.update(); 
marci@625
  1907
	backward_map.update();
marci@625
  1908
      }
marci@556
  1909
//       T get(Edge e) const { 
marci@556
  1910
// 	if (e.out_or_in) 
marci@556
  1911
// 	  return forward_map.get(e.out); 
marci@556
  1912
// 	else 
marci@556
  1913
// 	  return backward_map.get(e.in); 
marci@556
  1914
//       }
marci@556
  1915
    };
marci@556
  1916
  };
marci@556
  1917
marci@569
  1918
marci@569
  1919
marci@612
  1920
  /// For blocking flows.
marci@556
  1921
marci@792
  1922
  /// This graph wrapper is used for on-the-fly 
marci@792
  1923
  /// Dinits blocking flow computations.
marci@612
  1924
  /// For each node, an out-edge is stored which is used when the 
marci@612
  1925
  /// \code 
marci@612
  1926
  /// OutEdgeIt& first(OutEdgeIt&, const Node&)
marci@612
  1927
  /// \endcode
marci@612
  1928
  /// is called. 
marci@556
  1929
  ///
marci@792
  1930
  /// \author Marton Makai
marci@556
  1931
  template<typename Graph, typename FirstOutEdgesMap>
marci@556
  1932
  class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@650
  1933
  public:
marci@650
  1934
    typedef GraphWrapper<Graph> Parent; 
marci@556
  1935
  protected:
marci@556
  1936
    FirstOutEdgesMap* first_out_edges;
marci@556
  1937
  public:
marci@556
  1938
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@556
  1939
			     FirstOutEdgesMap& _first_out_edges) : 
marci@556
  1940
      GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@556
  1941
marci@556
  1942
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
  1943
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@777
  1944
    class OutEdgeIt : public Edge { 
marci@556
  1945
      friend class GraphWrapper<Graph>;
marci@556
  1946
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@777
  1947
      const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>* gw;
marci@556
  1948
    public:
marci@556
  1949
      OutEdgeIt() { }
marci@777
  1950
      //OutEdgeIt(const OutEdgeIt& e) : Edge(e), gw(e.gw) { }
marci@777
  1951
      OutEdgeIt(Invalid i) : Edge(i) { }
marci@777
  1952
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw, 
marci@777
  1953
		const Node& n) : 
marci@777
  1954
	Edge((*(_gw.first_out_edges))[n]), gw(&_gw) { }
marci@777
  1955
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw, 
marci@777
  1956
		const Edge& e) : 
marci@777
  1957
	Edge(e), gw(&_gw) { }
marci@777
  1958
      OutEdgeIt& operator++() { 
marci@777
  1959
	*(static_cast<Edge*>(this))=
marci@777
  1960
	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
marci@777
  1961
	return *this; 
marci@777
  1962
      }
marci@556
  1963
    };
marci@777
  1964
//     class InEdgeIt { 
marci@777
  1965
//       friend class GraphWrapper<Graph>;
marci@777
  1966
//       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@777
  1967
// //      typedef typename Graph::InEdgeIt GraphInEdgeIt;
marci@777
  1968
//       typename Graph::InEdgeIt e;
marci@777
  1969
//     public:
marci@777
  1970
//       InEdgeIt() { }
marci@777
  1971
//       InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@777
  1972
//       InEdgeIt(const Invalid& i) : e(i) { }
marci@777
  1973
//       InEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@777
  1974
// 	       const Node& _n) : 
marci@777
  1975
// 	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@777
  1976
//       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@777
  1977
//     };	
marci@556
  1978
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@777
  1979
//     class EdgeIt { 
marci@777
  1980
//       friend class GraphWrapper<Graph>;
marci@777
  1981
//       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@777
  1982
// //      typedef typename Graph::EdgeIt GraphEdgeIt;
marci@777
  1983
//       typename Graph::EdgeIt e;
marci@777
  1984
//     public:
marci@777
  1985
//       EdgeIt() { }
marci@777
  1986
//       EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@777
  1987
//       EdgeIt(const Invalid& i) : e(i) { }
marci@777
  1988
//       EdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@777
  1989
// 	e(*(_G.graph)) { }
marci@777
  1990
//       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@777
  1991
//     };
marci@556
  1992
marci@556
  1993
    using GraphWrapper<Graph>::first;
marci@556
  1994
//     NodeIt& first(NodeIt& i) const { 
marci@556
  1995
//       i=NodeIt(*this); return i;
marci@556
  1996
//     }
marci@556
  1997
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
  1998
      i=OutEdgeIt(*this, p); return i;
marci@556
  1999
    }
marci@777
  2000
//     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@777
  2001
//       i=InEdgeIt(*this, p); return i;
marci@777
  2002
//     }
marci@777
  2003
//     EdgeIt& first(EdgeIt& i) const { 
marci@777
  2004
//       i=EdgeIt(*this); return i;
marci@777
  2005
//     }
marci@556
  2006
marci@777
  2007
//     using GraphWrapper<Graph>::next;
marci@777
  2008
// //    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@777
  2009
//     OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@777
  2010
//     InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@777
  2011
//     EdgeIt& next(EdgeIt& i) const { this->graph->next(i.e); return i; }    
marci@556
  2012
    
marci@777
  2013
//     Node aNode(const OutEdgeIt& e) const { 
marci@777
  2014
//       return Node(this->graph->aNode(e.e)); }
marci@777
  2015
//     Node aNode(const InEdgeIt& e) const { 
marci@777
  2016
//       return Node(this->graph->aNode(e.e)); }
marci@777
  2017
//     Node bNode(const OutEdgeIt& e) const { 
marci@777
  2018
//       return Node(this->graph->bNode(e.e)); }
marci@777
  2019
//     Node bNode(const InEdgeIt& e) const { 
marci@777
  2020
//       return Node(this->graph->bNode(e.e)); }
marci@556
  2021
marci@777
  2022
    void erase(const Edge& e) const {
marci@777
  2023
      Node n=tail(e);
marci@777
  2024
      typename Graph::OutEdgeIt f(*graph, n);
marci@777
  2025
      ++f;
marci@777
  2026
      first_out_edges->set(n, f);
marci@556
  2027
    }
marci@556
  2028
  };
marci@556
  2029
marci@556
  2030
  ///@}
marci@556
  2031
marci@556
  2032
} //namespace hugo
marci@556
  2033
marci@556
  2034
#endif //HUGO_GRAPH_WRAPPER_H
marci@556
  2035