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