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