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