src/hugo/graph_wrapper.h
author alpar
Mon, 06 Sep 2004 09:21:35 +0000
changeset 808 9cabbdd73375
parent 777 a82713ed19f3
child 838 51dcd224455c
permissions -rw-r--r--
Bug: This file must be updated.
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