src/work/marci/graph_wrapper.h
author beckerjc
Thu, 29 Apr 2004 17:00:44 +0000
changeset 483 ce29ae5b2e1b
parent 438 a0a2709cf178
child 491 4804c967543d
permissions -rw-r--r--
UnionFind moved to include. Test compiles and runs cleanly.

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