marci@174: // -*- c++ -*-
marci@259: #ifndef HUGO_GRAPH_WRAPPER_H
marci@259: #define HUGO_GRAPH_WRAPPER_H
marci@76: 
marci@174: #include <invalid.h>
marci@368: #include <iter_map.h>
marci@174: 
alpar@105: namespace hugo {
marci@76: 
alpar@438:   // Graph wrappers
alpar@438: 
alpar@406:   /// \addtogroup gwrappers
alpar@344:   /// A main parts of HUGOlib are the different graph structures, 
marci@335:   /// generic graph algorithms, graph concepts which couple these, and 
marci@335:   /// graph wrappers. While the previous ones are more or less clear, the 
marci@335:   /// latter notion needs further explanation.
marci@335:   /// Graph wrappers are graph classes which serve for considering graph 
alpar@344:   /// structures in different ways. A short example makes the notion much 
alpar@344:   /// clearer. 
alpar@344:   /// Suppose that we have an instance \c g of a directed graph
alpar@344:   /// type say \c ListGraph and an algorithm 
marci@335:   /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
alpar@344:   /// is needed to run on the reversely oriented graph. 
alpar@344:   /// It may be expensive (in time or in memory usage) to copy 
alpar@344:   /// \c g with the reverse orientation. 
marci@335:   /// Thus, a wrapper class
marci@335:   /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@335:   /// The code looks as follows
marci@335:   /// \code
marci@335:   /// ListGraph g;
marci@335:   /// RevGraphWrapper<ListGraph> rgw(g);
marci@335:   /// int result=algorithm(rgw);
marci@335:   /// \endcode
alpar@344:   /// After running the algorithm, the original graph \c g 
alpar@344:   /// remains untouched. Thus the graph wrapper used above is to consider the 
alpar@344:   /// original graph with reverse orientation. 
marci@335:   /// This techniques gives rise to an elegant code, and 
marci@335:   /// based on stable graph wrappers, complex algorithms can be 
marci@335:   /// implemented easily. 
marci@335:   /// In flow, circulation and bipartite matching problems, the residual 
alpar@344:   /// graph is of particular importance. Combining a wrapper implementing 
alpar@344:   /// this, shortest path algorithms and minimum mean cycle algorithms, 
marci@335:   /// a range of weighted and cardinality optimization algorithms can be 
marci@335:   /// obtained. For lack of space, for other examples, 
alpar@344:   /// the interested user is referred to the detailed documentation of graph 
marci@335:   /// wrappers. 
alpar@344:   /// The behavior of graph wrappers can be very different. Some of them keep 
marci@335:   /// capabilities of the original graph while in other cases this would be 
alpar@344:   /// meaningless. This means that the concepts that they are a model of depend 
marci@335:   /// on the graph wrapper, and the wrapped graph(s). 
alpar@344:   /// If an edge of \c rgw is deleted, this is carried out by 
alpar@344:   /// deleting the corresponding edge of \c g. But for a residual 
marci@335:   /// graph, this operation has no sense. 
marci@335:   /// Let we stand one more example here to simplify your work. 
marci@335:   /// wrapper class
marci@335:   /// \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@335:   /// has constructor 
alpar@344:   /// <tt> RevGraphWrapper(Graph& _g)</tt>. 
marci@335:   /// This means that in a situation, 
alpar@344:   /// when a <tt> const ListGraph& </tt> reference to a graph is given, 
alpar@344:   /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
marci@335:   /// \code
marci@335:   /// int algorithm1(const ListGraph& g) {
marci@335:   ///   RevGraphWrapper<const ListGraph> rgw(g);
marci@335:   ///   return algorithm2(rgw);
marci@335:   /// }
marci@335:   /// \endcode
alpar@438: 
alpar@438:   /// \addtogroup gwrappers
alpar@438:   /// @{
alpar@438: 
alpar@438:   ///Base type for the Graph Wrappers
alpar@438: 
alpar@438:   ///This is the base type for the Graph Wrappers.
alpar@438:   ///\todo Some more docs...
alpar@438: 
marci@303:   template<typename Graph>
marci@303:   class GraphWrapper {
marci@212:   protected:
marci@303:     Graph* graph;
marci@212:   
marci@212:   public:
marci@311:     typedef Graph BaseGraph;
marci@303:     typedef Graph ParentGraph;
marci@212: 
marci@303: //     GraphWrapper() : graph(0) { }
marci@303:     GraphWrapper(Graph& _graph) : graph(&_graph) { }
marci@303: //     void setGraph(Graph& _graph) { graph=&_graph; }
marci@303: //     Graph& getGraph() const { return *graph; }
marci@303:  
marci@317: //    typedef typename Graph::Node Node;
marci@317:     class Node : public Graph::Node {
marci@317:       friend class GraphWrapper<Graph>;
marci@265:     public:
marci@317:       Node() { }
marci@317:       Node(const typename Graph::Node& _n) : Graph::Node(_n) { }
marci@317:       Node(const Invalid& i) : Graph::Node(i) { }
marci@317:     };
marci@317:     class NodeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       typename Graph::NodeIt n;
marci@317:      public:
marci@265:       NodeIt() { }
marci@317:       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@317:       NodeIt(const Invalid& i) : n(i) { }
marci@317:       NodeIt(const GraphWrapper<Graph>& _G) : n(*(_G.graph)) { }
marci@317:       operator Node() const { return Node(typename Graph::Node(n)); }
marci@265:     };
marci@317: //    typedef typename Graph::Edge Edge;
marci@317:     class Edge : public Graph::Edge {
marci@317:       friend class GraphWrapper<Graph>;
marci@317:     public:
marci@317:       Edge() { }
marci@317:       Edge(const typename Graph::Edge& _e) : Graph::Edge(_e) { }
marci@317:       Edge(const Invalid& i) : Graph::Edge(i) { }
marci@317:     };
marci@317:     class OutEdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       typename Graph::OutEdgeIt e;
marci@265:     public:
marci@265:       OutEdgeIt() { }
marci@317:       OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317:       OutEdgeIt(const Invalid& i) : e(i) { }
marci@317:       OutEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@317: 	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265:     };
marci@317:     class InEdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       typename Graph::InEdgeIt e;
marci@265:     public:
marci@265:       InEdgeIt() { }
marci@317:       InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317:       InEdgeIt(const Invalid& i) : e(i) { }
marci@317:       InEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@317: 	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265:     };
marci@303:     //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317:     class EdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       typename Graph::EdgeIt e;
marci@265:     public:
marci@265:       EdgeIt() { }
marci@317:       EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317:       EdgeIt(const Invalid& i) : e(i) { }
marci@317:       EdgeIt(const GraphWrapper<Graph>& _G) : e(*(_G.graph)) { }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265:     };
marci@303:    
marci@303:     NodeIt& first(NodeIt& i) const { 
marci@317:       i=NodeIt(*this); return i;
marci@265:     }
marci@303:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317:       i=OutEdgeIt(*this, p); return i;
marci@303:     }
marci@303:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317:       i=InEdgeIt(*this, p); return i;
marci@303:     }
marci@311:     EdgeIt& first(EdgeIt& i) const { 
marci@317:       i=EdgeIt(*this); return i;
marci@311:     }
marci@338: 
marci@317:     NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@317:     OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
marci@317:     InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
marci@317:     EdgeIt& next(EdgeIt& i) const { graph->next(i.e); return i; }    
marci@212: 
marci@379:     Node tail(const Edge& e) const { 
marci@379:       return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
marci@317:     Node head(const Edge& e) const { 
marci@317:       return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
marci@212: 
marci@317:     bool valid(const Node& n) const { 
marci@317:       return graph->valid(static_cast<typename Graph::Node>(n)); }
marci@317:     bool valid(const Edge& e) const { 
marci@317:       return graph->valid(static_cast<typename Graph::Edge>(e)); }
marci@212: 
marci@303:     int nodeNum() const { return graph->nodeNum(); }
marci@303:     int edgeNum() const { return graph->edgeNum(); }
marci@212:   
marci@317:     Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317:     Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317:     Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@317:     Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@212:   
marci@317:     Node addNode() const { return Node(graph->addNode()); }
marci@212:     Edge addEdge(const Node& tail, const Node& head) const { 
marci@317:       return Edge(graph->addEdge(tail, head)); }
marci@317: 
marci@317:     void erase(const Node& i) const { graph->erase(i); }
marci@317:     void erase(const Edge& i) const { graph->erase(i); }
marci@212:   
marci@303:     void clear() const { graph->clear(); }
marci@212:     
marci@389:     template<typename T> class NodeMap : public Graph::template NodeMap<T> { 
marci@389:       typedef typename Graph::template NodeMap<T> Parent;
marci@212:     public:
marci@389:       NodeMap(const GraphWrapper<Graph>& _G) :  Parent(*(_G.graph)) { }
marci@389:       NodeMap(const GraphWrapper<Graph>& _G, T a) : Parent(*(_G.graph), a) { }
marci@212:     };
marci@212: 
marci@389:     template<typename T> class EdgeMap : public Graph::template EdgeMap<T> { 
marci@389:       typedef typename Graph::template EdgeMap<T> Parent;
marci@212:     public:
marci@389:       EdgeMap(const GraphWrapper<Graph>& _G) : Parent(*(_G.graph)) { }
marci@389:       EdgeMap(const GraphWrapper<Graph>& _G, T a) : Parent(*(_G.graph), a) { }
marci@212:     };
marci@212:   };
marci@212: 
marci@338:   /// A graph wrapper which reverses the orientation of the edges.
marci@303: 
marci@338:   /// A graph wrapper which reverses the orientation of the edges.
marci@303:   template<typename Graph>
marci@303:   class RevGraphWrapper : public GraphWrapper<Graph> {
marci@230:   public:
marci@338: 
marci@338:     RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@338: 
marci@303:     typedef typename GraphWrapper<Graph>::Node Node;
marci@303:     typedef typename GraphWrapper<Graph>::Edge Edge;
marci@303:     //If Graph::OutEdgeIt is not defined
marci@279:     //and we do not want to use RevGraphWrapper::InEdgeIt,
marci@338:     //the typdef techinque does not work.
marci@338:     //Unfortunately all the typedefs are instantiated in templates.
marci@338:     //typedef typename GraphWrapper<Graph>::OutEdgeIt InEdgeIt;
marci@338:     //typedef typename GraphWrapper<Graph>::InEdgeIt OutEdgeIt;
marci@237: 
marci@338:     class OutEdgeIt { 
marci@338:       friend class GraphWrapper<Graph>;
marci@338:       friend class RevGraphWrapper<Graph>;
marci@379:       typename Graph::InEdgeIt e;
marci@338:     public:
marci@338:       OutEdgeIt() { }
marci@379:       OutEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@338:       OutEdgeIt(const Invalid& i) : e(i) { }
marci@338:       OutEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@338: 	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@338:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@338:     };
marci@338:     class InEdgeIt { 
marci@338:       friend class GraphWrapper<Graph>;
marci@338:       friend class RevGraphWrapper<Graph>;
marci@379:       typename Graph::OutEdgeIt e;
marci@338:     public:
marci@338:       InEdgeIt() { }
marci@379:       InEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@338:       InEdgeIt(const Invalid& i) : e(i) { }
marci@338:       InEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@338: 	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@338:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@338:     };
marci@238: 
marci@338:     using GraphWrapper<Graph>::first;
marci@338:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@338:       i=OutEdgeIt(*this, p); return i;
marci@338:     }
marci@338:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@338:       i=InEdgeIt(*this, p); return i;
marci@338:     }
marci@338: 
marci@338:     using GraphWrapper<Graph>::next;
marci@389:     OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389:     InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@338: 
marci@389:     Node aNode(const OutEdgeIt& e) const { 
marci@389:       return Node(this->graph->aNode(e.e)); }
marci@389:     Node aNode(const InEdgeIt& e) const { 
marci@389:       return Node(this->graph->aNode(e.e)); }
marci@389:     Node bNode(const OutEdgeIt& e) const { 
marci@389:       return Node(this->graph->bNode(e.e)); }
marci@389:     Node bNode(const InEdgeIt& e) const { 
marci@389:       return Node(this->graph->bNode(e.e)); }
marci@379: 
marci@379:     Node tail(const Edge& e) const { 
marci@379:       return GraphWrapper<Graph>::head(e); }
marci@379:     Node head(const Edge& e) const { 
marci@379:       return GraphWrapper<Graph>::tail(e); }
marci@379: 
marci@76:   };
marci@76: 
marci@335:   /// Wrapper for hiding nodes and edges from a graph.
marci@335:   
marci@335:   /// This wrapper shows a graph with filtered node-set and 
klao@363:   /// edge-set. The quick brown fox iterator jumps over 
marci@335:   /// the lazy dog nodes or edges if the values for them are false 
marci@335:   /// in the bool maps. 
marci@311:   template<typename Graph, typename NodeFilterMap, 
marci@311: 	   typename EdgeFilterMap>
marci@303:   class SubGraphWrapper : public GraphWrapper<Graph> {
marci@263:   protected:
marci@311:     NodeFilterMap* node_filter_map;
marci@311:     EdgeFilterMap* edge_filter_map;
marci@263:   public:
marci@338: 
marci@311:     SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@311: 		    EdgeFilterMap& _edge_filter_map) : 
marci@311:       GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
marci@311:       edge_filter_map(&_edge_filter_map) { }  
marci@263: 
marci@317:     typedef typename GraphWrapper<Graph>::Node Node;
marci@317:     class NodeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317:       typename Graph::NodeIt n;
marci@317:      public:
marci@311:       NodeIt() { }
marci@317:       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@317:       NodeIt(const Invalid& i) : n(i) { }
marci@311:       NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@317: 	n(*(_G.graph)) { 
marci@317: 	while (_G.graph->valid(n) && !(*(_G.node_filter_map))[n]) 
marci@317: 	  _G.graph->next(n);
marci@311:       }
marci@317:       operator Node() const { return Node(typename Graph::Node(n)); }
marci@311:     };
marci@317:     typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317:     class OutEdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317:       typename Graph::OutEdgeIt e;
marci@311:     public:
marci@311:       OutEdgeIt() { }
marci@317:       OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317:       OutEdgeIt(const Invalid& i) : e(i) { }
marci@317:       OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@317: 		const Node& _n) : 
marci@317: 	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@317:       	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317: 	  _G.graph->next(e);
marci@311:       }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311:     };
marci@317:     class InEdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317:       typename Graph::InEdgeIt e;
marci@311:     public:
marci@311:       InEdgeIt() { }
marci@317:       InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317:       InEdgeIt(const Invalid& i) : e(i) { }
marci@311:       InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@317: 	       const Node& _n) : 
marci@317: 	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@317:       	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317: 	  _G.graph->next(e);
marci@311:       }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311:     };
marci@317:     //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317:     class EdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317:       typename Graph::EdgeIt e;
marci@311:     public:
marci@311:       EdgeIt() { }
marci@317:       EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317:       EdgeIt(const Invalid& i) : e(i) { }
marci@311:       EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@317: 	e(*(_G.graph)) { 
marci@317:       	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317: 	  _G.graph->next(e);
marci@311:       }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311:     };
marci@317: 
marci@317:     NodeIt& first(NodeIt& i) const { 
marci@317:       i=NodeIt(*this); return i;
marci@263:     }
marci@317:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317:       i=OutEdgeIt(*this, p); return i;
marci@311:     }
marci@317:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317:       i=InEdgeIt(*this, p); return i;
marci@311:     }
marci@317:     EdgeIt& first(EdgeIt& i) const { 
marci@317:       i=EdgeIt(*this); return i;
marci@263:     }
marci@263:     
marci@311:     NodeIt& next(NodeIt& i) const {
marci@389:       this->graph->next(i.n); 
marci@389:       while (this->graph->valid(i) && !(*node_filter_map)[i.n]) { 
marci@389: 	this->graph->next(i.n); }
marci@311:       return i;
marci@311:     }
marci@311:     OutEdgeIt& next(OutEdgeIt& i) const {
marci@389:       this->graph->next(i.e); 
marci@389:       while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@389: 	this->graph->next(i.e); }
marci@311:       return i;
marci@311:     }
marci@311:     InEdgeIt& next(InEdgeIt& i) const {
marci@389:       this->graph->next(i.e); 
marci@389:       while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@389: 	this->graph->next(i.e); }
marci@311:       return i;
marci@311:     }
marci@311:     EdgeIt& next(EdgeIt& i) const {
marci@389:       this->graph->next(i.e); 
marci@389:       while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@389: 	this->graph->next(i.e); }
marci@311:       return i;
marci@311:     }
marci@311: 
marci@389:     Node aNode(const OutEdgeIt& e) const { 
marci@389:       return Node(this->graph->aNode(e.e)); }
marci@389:     Node aNode(const InEdgeIt& e) const { 
marci@389:       return Node(this->graph->aNode(e.e)); }
marci@389:     Node bNode(const OutEdgeIt& e) const { 
marci@389:       return Node(this->graph->bNode(e.e)); }
marci@389:     Node bNode(const InEdgeIt& e) const { 
marci@389:       return Node(this->graph->bNode(e.e)); }
marci@323: 
alpar@357:     ///\todo
alpar@357:     ///Some doki, please.
marci@323:     void hide(const Node& n) const { node_filter_map->set(n, false); }
alpar@357:     ///\todo
alpar@357:     ///Some doki, please.
marci@323:     void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@323: 
alpar@357:     ///\todo
alpar@357:     ///Some doki, please.
marci@323:     void unHide(const Node& n) const { node_filter_map->set(n, true); }
alpar@357:     ///\todo
alpar@357:     ///Some doki, please.
marci@323:     void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@323: 
alpar@357:     ///\todo
alpar@357:     ///Some doki, please.
marci@323:     bool hidden(const Node& n) const { return (*node_filter_map)[n]; }
alpar@357:     ///\todo
alpar@357:     ///Some doki, please.
marci@323:     bool hidden(const Edge& e) const { return (*edge_filter_map)[e]; }
marci@263:   };
marci@155: 
alpar@356:   /// A wrapper for forgetting the orientation of a graph.
marci@317: 
alpar@356:   /// A wrapper for getting an undirected graph by forgetting
alpar@356:   /// the orientation of a directed one.
marci@303:   template<typename Graph>
marci@303:   class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@303:   public:
marci@303:     typedef typename GraphWrapper<Graph>::Node Node;
marci@303:     typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@317:     typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317:     typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@236: 
marci@303:     UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@158: 
marci@317:     class OutEdgeIt {
marci@303:       friend class UndirGraphWrapper<Graph>;
marci@158:       bool out_or_in; //true iff out
marci@317:       typename Graph::OutEdgeIt out;
marci@317:       typename Graph::InEdgeIt in;
marci@158:     public:
marci@317:       OutEdgeIt() { }
marci@317:       OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@317:       OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@317: 	out_or_in=true; _G.graph->first(out, _n);
marci@317: 	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@174:       } 
marci@317:       operator Edge() const { 
marci@317: 	if (out_or_in) return Edge(out); else return Edge(in); 
marci@158:       }
marci@158:     };
marci@158: 
marci@317: //FIXME InEdgeIt
marci@238:     typedef OutEdgeIt InEdgeIt; 
marci@238: 
marci@338:     using GraphWrapper<Graph>::first;
marci@338: //     NodeIt& first(NodeIt& i) const { 
marci@338: //       i=NodeIt(*this); return i;
marci@338: //     }
marci@317:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317:       i=OutEdgeIt(*this, p); return i;
marci@317:     }
marci@317: //FIXME
marci@317: //     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317: //       i=InEdgeIt(*this, p); return i;
marci@317: //     }
marci@338: //     EdgeIt& first(EdgeIt& i) const { 
marci@338: //       i=EdgeIt(*this); return i;
marci@338: //     }
marci@238: 
marci@338:     using GraphWrapper<Graph>::next;
marci@338: //     NodeIt& next(NodeIt& n) const {
marci@338: //       GraphWrapper<Graph>::next(n);
marci@338: //       return n;
marci@338: //     }
marci@158:     OutEdgeIt& next(OutEdgeIt& e) const {
marci@158:       if (e.out_or_in) {
marci@389: 	typename Graph::Node n=this->graph->tail(e.out);
marci@389: 	this->graph->next(e.out);
marci@389: 	if (!this->graph->valid(e.out)) { 
marci@389: 	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@158:       } else {
marci@389: 	this->graph->next(e.in);
marci@158:       }
marci@158:       return e;
marci@158:     }
marci@317:     //FIXME InEdgeIt
marci@338: //     EdgeIt& next(EdgeIt& e) const {
marci@338: //       GraphWrapper<Graph>::next(n);
marci@338: // //      graph->next(e.e);
marci@338: //       return e;
marci@338: //     }
marci@238: 
marci@238:     Node aNode(const OutEdgeIt& e) const { 
marci@389:       if (e.out_or_in) return this->graph->tail(e); else 
marci@389: 	return this->graph->head(e); }
marci@238:     Node bNode(const OutEdgeIt& e) const { 
marci@389:       if (e.out_or_in) return this->graph->head(e); else 
marci@389: 	return this->graph->tail(e); }
marci@338:   };
marci@158:   
marci@338:   /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@238: 
marci@338:   /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@330:   template<typename Graph, typename Number, 
marci@330: 	   typename CapacityMap, typename FlowMap>
marci@311:   class ResGraphWrapper : public GraphWrapper<Graph> {
marci@199:   protected:
marci@330:     const CapacityMap* capacity;
marci@155:     FlowMap* flow;
marci@155:   public:
marci@168: 
marci@330:     ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@330: 		    FlowMap& _flow) : 
marci@330:       GraphWrapper<Graph>(_graph), capacity(&_capacity), flow(&_flow) { }
marci@168: 
marci@174:     class Edge; 
marci@155:     class OutEdgeIt; 
marci@174:     friend class Edge; 
marci@155:     friend class OutEdgeIt; 
marci@76: 
marci@311:     typedef typename GraphWrapper<Graph>::Node Node;
marci@311:     typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@317:     class Edge : public Graph::Edge {
marci@330:       friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@155:     protected:
marci@317:       bool forward; //true, iff forward
marci@317: //      typename Graph::Edge e;
marci@155:     public:
marci@317:       Edge() { }
marci@317:       Edge(const typename Graph::Edge& _e, bool _forward) : 
marci@317: 	Graph::Edge(_e), forward(_forward) { }
marci@317:       Edge(const Invalid& i) : Graph::Edge(i), forward(false) { }
marci@317: //the unique invalid iterator
marci@174:       friend bool operator==(const Edge& u, const Edge& v) { 
marci@317: 	return (v.forward==u.forward && 
marci@317: 		static_cast<typename Graph::Edge>(u)==
marci@317: 		static_cast<typename Graph::Edge>(v));
marci@174:       } 
marci@174:       friend bool operator!=(const Edge& u, const Edge& v) { 
marci@317: 	return (v.forward!=u.forward || 
marci@317: 		static_cast<typename Graph::Edge>(u)!=
marci@317: 		static_cast<typename Graph::Edge>(v));
marci@174:       } 
marci@155:     };
marci@338: 
marci@317:     class OutEdgeIt {
marci@330:       friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317:     protected:
marci@317:       typename Graph::OutEdgeIt out;
marci@317:       typename Graph::InEdgeIt in;
marci@317:       bool forward;
marci@155:     public:
marci@155:       OutEdgeIt() { }
marci@168:       //FIXME
marci@317: //      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@317:       OutEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@317: //the unique invalid iterator
marci@330:       OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@317: 	forward=true;
marci@303: 	resG.graph->first(out, v);
marci@317: 	while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@303: 	if (!resG.graph->valid(out)) {
marci@317: 	  forward=false;
marci@303: 	  resG.graph->first(in, v);
marci@317: 	  while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@155: 	}
marci@155:       }
marci@317:       operator Edge() const { 
marci@317: //	Edge e;
marci@317: //	e.forward=this->forward;
marci@317: //	if (this->forward) e=out; else e=in;
marci@317: //	return e;
marci@317: 	if (this->forward) 
marci@317: 	  return Edge(out, this->forward); 
marci@317: 	else 
marci@317: 	  return Edge(in, this->forward);
marci@317:       }
marci@317:     };
marci@263: 
marci@317:     class InEdgeIt {
marci@330:       friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317:     protected:
marci@317:       typename Graph::OutEdgeIt out;
marci@317:       typename Graph::InEdgeIt in;
marci@317:       bool forward;
marci@317:     public:
marci@317:       InEdgeIt() { }
marci@317:       //FIXME
marci@317: //      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@317:       InEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@317: //the unique invalid iterator
marci@330:       InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@317: 	forward=true;
marci@317: 	resG.graph->first(in, v);
marci@317: 	while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@317: 	if (!resG.graph->valid(in)) {
marci@317: 	  forward=false;
marci@317: 	  resG.graph->first(out, v);
marci@317: 	  while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@317: 	}
marci@317:       }
marci@317:       operator Edge() const { 
marci@317: //	Edge e;
marci@317: //	e.forward=this->forward;
marci@317: //	if (this->forward) e=out; else e=in;
marci@317: //	return e;
marci@317: 	if (this->forward) 
marci@317: 	  return Edge(in, this->forward); 
marci@317: 	else 
marci@317: 	  return Edge(out, this->forward);
marci@317:       }
marci@317:     };
marci@317: 
marci@317:     class EdgeIt {
marci@330:       friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317:     protected:
marci@317:       typename Graph::EdgeIt e;
marci@317:       bool forward;
marci@155:     public:
marci@174:       EdgeIt() { }
marci@317:       EdgeIt(const Invalid& i) : e(i), forward(false) { }
marci@330:       EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG) { 
marci@317: 	forward=true;
marci@317: 	resG.graph->first(e);
marci@317: 	while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@317: 	if (!resG.graph->valid(e)) {
marci@317: 	  forward=false;
marci@317: 	  resG.graph->first(e);
marci@317: 	  while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@155: 	}
marci@155:       }
marci@317:       operator Edge() const { 
marci@317: 	return Edge(e, this->forward);
marci@317:       }
marci@317:     };
marci@155: 
marci@338:     using GraphWrapper<Graph>::first;
marci@338: //     NodeIt& first(NodeIt& i) const { 
marci@338: //       i=NodeIt(*this); return i;
marci@338: //     }
marci@311:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317:       i=OutEdgeIt(*this, p); return i;
marci@311:     }
marci@317: //    FIXME not tested
marci@317:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317:       i=InEdgeIt(*this, p); return i;
marci@317:     }
marci@317:     EdgeIt& first(EdgeIt& i) const { 
marci@317:       i=EdgeIt(*this); return i;
marci@155:     }
marci@338:   
marci@338:     using GraphWrapper<Graph>::next;
marci@338: //    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@155:     OutEdgeIt& next(OutEdgeIt& e) const { 
marci@317:       if (e.forward) {
marci@389: 	Node v=this->graph->aNode(e.out);
marci@389: 	this->graph->next(e.out);
marci@389: 	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@389: 	  this->graph->next(e.out); }
marci@389: 	if (!this->graph->valid(e.out)) {
marci@317: 	  e.forward=false;
marci@389: 	  this->graph->first(e.in, v); 
marci@389: 	  while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@389: 	    this->graph->next(e.in); }
marci@155: 	}
marci@155:       } else {
marci@389: 	this->graph->next(e.in);
marci@389: 	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@389: 	  this->graph->next(e.in); } 
marci@155:       }
marci@155:       return e;
marci@155:     }
marci@317: //     FIXME Not tested
marci@317:     InEdgeIt& next(InEdgeIt& e) const { 
marci@317:       if (e.forward) {
marci@389: 	Node v=this->graph->aNode(e.in);
marci@389: 	this->graph->next(e.in);
marci@389: 	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@389: 	  this->graph->next(e.in); }
marci@389: 	if (!this->graph->valid(e.in)) {
marci@317: 	  e.forward=false;
marci@389: 	  this->graph->first(e.out, v); 
marci@389: 	  while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@389: 	    this->graph->next(e.out); }
marci@317: 	}
marci@317:       } else {
marci@389: 	this->graph->next(e.out);
marci@389: 	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@389: 	  this->graph->next(e.out); } 
marci@317:       }
marci@317:       return e;
marci@317:     }
marci@317:     EdgeIt& next(EdgeIt& e) const {
marci@317:       if (e.forward) {
marci@389: 	this->graph->next(e.e);
marci@389: 	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@389: 	  this->graph->next(e.e); }
marci@389: 	if (!this->graph->valid(e.e)) {
marci@317: 	  e.forward=false;
marci@389: 	  this->graph->first(e.e); 
marci@389: 	  while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@389: 	    this->graph->next(e.e); }
marci@155: 	}
marci@317:       } else {
marci@389: 	this->graph->next(e.e);
marci@389: 	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@389: 	  this->graph->next(e.e); } 
marci@155:       }
marci@317:       return e;
marci@317:     }
marci@76: 
marci@174:     Node tail(Edge e) const { 
marci@389:       return ((e.forward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@174:     Node head(Edge e) const { 
marci@389:       return ((e.forward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@76: 
marci@174:     Node aNode(OutEdgeIt e) const { 
marci@389:       return ((e.forward) ? this->graph->aNode(e.out) : 
marci@389: 	      this->graph->aNode(e.in)); }
marci@174:     Node bNode(OutEdgeIt e) const { 
marci@389:       return ((e.forward) ? this->graph->bNode(e.out) : 
marci@389: 	      this->graph->bNode(e.in)); }
marci@76: 
marci@376:     Node aNode(InEdgeIt e) const { 
marci@389:       return ((e.forward) ? this->graph->aNode(e.in) : 
marci@389: 	      this->graph->aNode(e.out)); }
marci@376:     Node bNode(InEdgeIt e) const { 
marci@389:       return ((e.forward) ? this->graph->bNode(e.in) : 
marci@389: 	      this->graph->bNode(e.out)); }
marci@376: 
marci@338: //    int nodeNum() const { return graph->nodeNum(); }
marci@263:     //FIXME
marci@338:     void edgeNum() const { }
marci@303:     //int edgeNum() const { return graph->edgeNum(); }
marci@263: 
marci@263: 
marci@317: //    int id(Node v) const { return graph->id(v); }
marci@155: 
marci@317:     bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@174:     bool valid(Edge e) const { 
marci@389:       return this->graph->valid(e);
marci@317: 	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@317:     }
marci@155: 
marci@174:     void augment(const Edge& e, Number a) const {
marci@317:       if (e.forward)  
marci@303: // 	flow->set(e.out, flow->get(e.out)+a);
marci@317: 	flow->set(e, (*flow)[e]+a);
marci@168:       else  
marci@303: // 	flow->set(e.in, flow->get(e.in)-a);
marci@317: 	flow->set(e, (*flow)[e]-a);
marci@168:     }
marci@168: 
marci@269:     Number resCap(const Edge& e) const { 
marci@317:       if (e.forward) 
marci@303: //	return (capacity->get(e.out)-flow->get(e.out)); 
marci@317: 	return ((*capacity)[e]-(*flow)[e]); 
marci@168:       else 
marci@303: //	return (flow->get(e.in)); 
marci@317: 	return ((*flow)[e]); 
marci@168:     }
marci@168: 
marci@317: //     Number resCap(typename Graph::OutEdgeIt out) const { 
marci@317: // //      return (capacity->get(out)-flow->get(out)); 
marci@317: //       return ((*capacity)[out]-(*flow)[out]); 
marci@317: //     }
marci@168:     
marci@317: //     Number resCap(typename Graph::InEdgeIt in) const { 
marci@317: // //      return (flow->get(in)); 
marci@317: //       return ((*flow)[in]); 
marci@317: //     }
marci@168: 
marci@155:     template <typename T>
marci@155:     class EdgeMap {
marci@389:       typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@155:     public:
marci@330:       EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@330:       EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@174:       void set(Edge e, T a) { 
marci@317: 	if (e.forward) 
marci@155: 	  forward_map.set(e.out, a); 
marci@155: 	else 
marci@155: 	  backward_map.set(e.in, a); 
marci@155:       }
marci@303:       T operator[](Edge e) const { 
marci@317: 	if (e.forward) 
marci@303: 	  return forward_map[e.out]; 
marci@155: 	else 
marci@303: 	  return backward_map[e.in]; 
marci@155:       }
marci@303: //       T get(Edge e) const { 
marci@303: // 	if (e.out_or_in) 
marci@303: // 	  return forward_map.get(e.out); 
marci@303: // 	else 
marci@303: // 	  return backward_map.get(e.in); 
marci@303: //       }
marci@155:     };
marci@168:   };
marci@168: 
marci@338:   /// ErasingFirstGraphWrapper for blocking flows.
marci@317: 
marci@338:   /// ErasingFirstGraphWrapper for blocking flows.
marci@303:   template<typename Graph, typename FirstOutEdgesMap>
marci@303:   class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@269:   protected:
marci@269:     FirstOutEdgesMap* first_out_edges;
marci@269:   public:
marci@303:     ErasingFirstGraphWrapper(Graph& _graph, 
marci@303: 			     FirstOutEdgesMap& _first_out_edges) : 
marci@303:       GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@269: 
marci@317:     typedef typename GraphWrapper<Graph>::Node Node;
marci@338: //     class NodeIt { 
marci@338: //       friend class GraphWrapper<Graph>;
marci@338: //       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@338: //       typename Graph::NodeIt n;
marci@338: //      public:
marci@338: //       NodeIt() { }
marci@338: //       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@338: //       NodeIt(const Invalid& i) : n(i) { }
marci@338: //       NodeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@338: // 	n(*(_G.graph)) { }
marci@338: //       operator Node() const { return Node(typename Graph::Node(n)); }
marci@338: //     };
marci@317:     typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317:     class OutEdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317: //      typedef typename Graph::OutEdgeIt GraphOutEdgeIt;
marci@317:       typename Graph::OutEdgeIt e;
marci@311:     public:
marci@311:       OutEdgeIt() { }
marci@317:       OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317:       OutEdgeIt(const Invalid& i) : e(i) { }
marci@311:       OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@317: 		const Node& _n) : 
marci@317: 	e((*_G.first_out_edges)[_n]) { }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311:     };
marci@317:     class InEdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317: //      typedef typename Graph::InEdgeIt GraphInEdgeIt;
marci@317:       typename Graph::InEdgeIt e;
marci@311:     public:
marci@311:       InEdgeIt() { }
marci@317:       InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317:       InEdgeIt(const Invalid& i) : e(i) { }
marci@311:       InEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@317: 	       const Node& _n) : 
marci@317: 	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311:     };
marci@311:     //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317:     class EdgeIt { 
marci@317:       friend class GraphWrapper<Graph>;
marci@317:       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317: //      typedef typename Graph::EdgeIt GraphEdgeIt;
marci@317:       typename Graph::EdgeIt e;
marci@311:     public:
marci@311:       EdgeIt() { }
marci@317:       EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317:       EdgeIt(const Invalid& i) : e(i) { }
marci@311:       EdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@317: 	e(*(_G.graph)) { }
marci@317:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311:     };
marci@311: 
marci@338:     using GraphWrapper<Graph>::first;
marci@338: //     NodeIt& first(NodeIt& i) const { 
marci@338: //       i=NodeIt(*this); return i;
marci@338: //     }
marci@317:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317:       i=OutEdgeIt(*this, p); return i;
marci@269:     }
marci@317:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317:       i=InEdgeIt(*this, p); return i;
marci@311:     }
marci@317:     EdgeIt& first(EdgeIt& i) const { 
marci@317:       i=EdgeIt(*this); return i;
marci@311:     }
marci@311: 
marci@338:     using GraphWrapper<Graph>::next;
marci@338: //    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@389:     OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389:     InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389:     EdgeIt& next(EdgeIt& i) const { this->graph->next(i.e); return i; }    
marci@317:     
marci@389:     Node aNode(const OutEdgeIt& e) const { 
marci@389:       return Node(this->graph->aNode(e.e)); }
marci@389:     Node aNode(const InEdgeIt& e) const { 
marci@389:       return Node(this->graph->aNode(e.e)); }
marci@389:     Node bNode(const OutEdgeIt& e) const { 
marci@389:       return Node(this->graph->bNode(e.e)); }
marci@389:     Node bNode(const InEdgeIt& e) const { 
marci@389:       return Node(this->graph->bNode(e.e)); }
marci@311: 
marci@269:     void erase(const OutEdgeIt& e) const {
marci@269:       OutEdgeIt f=e;
marci@269:       this->next(f);
marci@317:       first_out_edges->set(this->tail(e), f.e);
marci@269:     }
marci@269:   };
marci@269: 
marci@368:   /// A wrapper for composing a bipartite graph.
marci@371:   /// \c _graph have to be a reference to a graph of type \c Graph 
marci@371:   /// and \c _s_false_t_true_map is an \c IterableBoolMap 
marci@368:   /// reference containing the elements for the 
marci@371:   /// color classes S and T. \c _graph is to be referred to an undirected 
marci@371:   /// graph or a directed graph with edges oriented from S to T.
marci@368:   template<typename Graph> 
marci@368:   class BipartiteGraphWrapper : public GraphWrapper<Graph> {
marci@389:     typedef IterableBoolMap< typename Graph::template NodeMap<int> > 
marci@389:     SFalseTTrueMap;
marci@368:     SFalseTTrueMap* s_false_t_true_map;
marci@393: 
marci@368:   public:
marci@409:     //marci
marci@409:     //FIXME vhogy igy kellene, csak az en forditom nem eszi meg
marci@409:     //static const bool S_CLASS=false;
marci@409:     //static const bool T_CLASS=true;
marci@379:     
marci@409:     bool S_CLASS;
marci@409:     bool T_CLASS;
marci@409: 
marci@368:     BipartiteGraphWrapper(Graph& _graph, SFalseTTrueMap& _s_false_t_true_map) 
marci@409:       : GraphWrapper<Graph>(_graph), s_false_t_true_map(&_s_false_t_true_map), 
marci@409:       S_CLASS(false), T_CLASS(true) { }
marci@368:     typedef typename GraphWrapper<Graph>::Node Node;
marci@368:     //using GraphWrapper<Graph>::NodeIt;
marci@368:     typedef typename GraphWrapper<Graph>::Edge Edge;
marci@368:     //using GraphWrapper<Graph>::EdgeIt;
marci@393:     class ClassNodeIt;
marci@393:     friend class ClassNodeIt;
marci@393:     class OutEdgeIt;
marci@393:     friend class OutEdgeIt;
marci@393:     class InEdgeIt;
marci@393:     friend class InEdgeIt;
marci@379:     class ClassNodeIt {
marci@393:       friend class BipartiteGraphWrapper<Graph>;
marci@393:     protected:
marci@368:       Node n;
marci@368:     public:
marci@379:       ClassNodeIt() { }
marci@379:       ClassNodeIt(const Invalid& i) : n(i) { }
marci@379:       ClassNodeIt(const BipartiteGraphWrapper<Graph>& _G, bool _class) { 
marci@379: 	_G.s_false_t_true_map->first(n, _class); 
marci@368:       }
marci@381:       //FIXME needed in new concept, important here
marci@381:       ClassNodeIt(const Node& _n) : n(_n) { }
marci@368:       operator Node() const { return n; }
marci@368:     };
marci@379: //     class SNodeIt {
marci@379: //       Node n;
marci@379: //     public:
marci@379: //       SNodeIt() { }
marci@379: //       SNodeIt(const Invalid& i) : n(i) { }
marci@379: //       SNodeIt(const BipartiteGraphWrapper<Graph>& _G) { 
marci@379: // 	_G.s_false_t_true_map->first(n, false); 
marci@379: //       }
marci@379: //       operator Node() const { return n; }
marci@379: //     };
marci@379: //     class TNodeIt {
marci@379: //       Node n;
marci@379: //     public:
marci@379: //       TNodeIt() { }
marci@379: //       TNodeIt(const Invalid& i) : n(i) { }
marci@379: //       TNodeIt(const BipartiteGraphWrapper<Graph>& _G) { 
marci@379: // 	_G.s_false_t_true_map->first(n, true); 
marci@379: //       }
marci@379: //       operator Node() const { return n; }
marci@379: //     };
marci@368:     class OutEdgeIt { 
marci@393:       friend class BipartiteGraphWrapper<Graph>;
marci@393:     protected:
marci@368:       typename Graph::OutEdgeIt e;
marci@368:     public:
marci@368:       OutEdgeIt() { }
marci@368:       OutEdgeIt(const Invalid& i) : e(i) { }
marci@368:       OutEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
marci@368: 	if (!(*(_G.s_false_t_true_map))[_n]) 
marci@379: 	  e=typename Graph::OutEdgeIt(*(_G.graph), typename Graph::Node(_n));
marci@368: 	else 
marci@368: 	  e=INVALID;
marci@368:       }
marci@368:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@368:     };
marci@368:     class InEdgeIt { 
marci@393:       friend class BipartiteGraphWrapper<Graph>;
marci@393:     protected:
marci@368:       typename Graph::InEdgeIt e;
marci@368:     public:
marci@368:       InEdgeIt() { }
marci@368:       InEdgeIt(const Invalid& i) : e(i) { }
marci@368:       InEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
marci@368: 	if ((*(_G.s_false_t_true_map))[_n]) 
marci@379: 	  e=typename Graph::InEdgeIt(*(_G.graph), typename Graph::Node(_n));
marci@368: 	else 
marci@368: 	  e=INVALID;
marci@368:       }
marci@368:       operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@368:     };
marci@368: 
marci@368:     using GraphWrapper<Graph>::first;
marci@379:     ClassNodeIt& first(ClassNodeIt& n, bool _class) const { 
marci@393:       n=ClassNodeIt(*this, _class) ; return n; }
marci@379: //    SNodeIt& first(SNodeIt& n) const { n=SNodeIt(*this); return n; }
marci@379: //    TNodeIt& first(TNodeIt& n) const { n=TNodeIt(*this); return n; }
marci@379:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@379:       i=OutEdgeIt(*this, p); return i;
marci@379:     }
marci@379:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@379:       i=InEdgeIt(*this, p); return i;
marci@379:     }
marci@368: 
marci@368:     using GraphWrapper<Graph>::next;
marci@379:     ClassNodeIt& next(ClassNodeIt& n) const { 
marci@393:       this->s_false_t_true_map->next(n.n); return n; 
marci@368:     }
marci@379: //     SNodeIt& next(SNodeIt& n) const { 
marci@379: //       this->s_false_t_true_map->next(n); return n; 
marci@379: //     }
marci@379: //     TNodeIt& next(TNodeIt& n) const { 
marci@379: //       this->s_false_t_true_map->next(n); return n; 
marci@379: //     }
marci@389:     OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@389:     InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@368: 
marci@368:     Node tail(const Edge& e) { 
marci@368:       if (!(*(this->s_false_t_true_map))[this->graph->tail(e)]) 
marci@368: 	return Node(this->graph->tail(e));
marci@368:       else
marci@368: 	return Node(this->graph->head(e));	
marci@368:     }
marci@368:     Node head(const Edge& e) { 
marci@368:       if (!(*(this->s_false_t_true_map))[this->graph->tail(e)]) 
marci@368: 	return Node(this->graph->head(e));
marci@368:       else
marci@368: 	return Node(this->graph->tail(e));	
marci@368:     }
marci@368: 
marci@368:     Node aNode(const OutEdgeIt& e) const { 
marci@368:       return Node(this->graph->aNode(e.e)); 
marci@368:     }
marci@368:     Node aNode(const InEdgeIt& e) const { 
marci@368:       return Node(this->graph->aNode(e.e)); 
marci@368:     }
marci@368:     Node bNode(const OutEdgeIt& e) const { 
marci@368:       return Node(this->graph->bNode(e.e)); 
marci@368:     }
marci@368:     Node bNode(const InEdgeIt& e) const { 
marci@368:       return Node(this->graph->bNode(e.e)); 
marci@368:     }
marci@379: 
marci@379:     bool inSClass(const Node& n) const {
marci@381:       return !(*(this->s_false_t_true_map))[n];
marci@379:     }
marci@379:     bool inTClass(const Node& n) const {
marci@381:       return (*(this->s_false_t_true_map))[n];
marci@379:     }
marci@368:   };
marci@368: 
marci@435:   template<typename Graph>
marci@435:   class stGraphWrapper;
marci@435: 
marci@435: //   template<typename Graph> 
marci@435: //   std::ostream& 
marci@435: //   operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Node& i) { 
marci@435: //     os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")"; 
marci@435: //     return os; 
marci@435: //   }
marci@435: //   template<typename Graph> 
marci@435: //   std::ostream& 
marci@435: //   operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Edge& i) { 
marci@435: //     os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec << 
marci@435: //       " node: " << i.n << ")"; 
marci@435: //     return os; 
marci@435: //   }
marci@341: 
marci@379:   /// experimentral, do not try it.
marci@379:   /// It eats a bipartite graph, oriented from S to T.
marci@379:   /// Such one can be made e.g. by the above wrapper.
marci@379:   template<typename Graph>
marci@379:   class stGraphWrapper : public GraphWrapper<Graph> {
marci@379:   public:
marci@379:     class Node; 
marci@381:     friend class Node;
marci@379: //GN, int
marci@379: //0 normalis, 1 s, 2, true, ez az iteralasi sorrend, 
marci@379: //es a vege a false azaz (invalid, 3)    
marci@379:     class NodeIt;
marci@381:     friend class NodeIt;
marci@379: //GNI, int
marci@379:     class Edge;
marci@381:     friend class Edge;
marci@379: //GE, int, GN
marci@379: //0 normalis, 1 s->vmi, 2 vmi->t, ez a sorrend,
marci@379: //invalid: (invalid, 3, invalid)
marci@379:     class OutEdgeIt;
marci@381:     friend class OutEdgeIt;
marci@379: //GO, int, GNI
marci@379: //normalis pontbol (first, 0, invalid), ..., (invalid, 2, vmi), ... (invalid, 3, invalid)
marci@379: //s-bol (invalid, 1, first), ... (invalid, 3, invalid)
marci@379: //t-bol (invalid, 3, invalid)
marci@379:     class InEdgeIt;
marci@381:     friend class InEdgeIt;
marci@379: //GI, int, GNI
marci@379: //normalis pontbol (first, 0, invalid), ..., (invalid, 1, vmi), ... (invalid, 3, invalid)
marci@379: //s-be (invalid, 3, invalid)
marci@379: //t-be (invalid, 2, first), ... (invalid, 3, invalid)
marci@379:     class EdgeIt;
marci@381:     friend class EdgeIt;
marci@379: //(first, 0, invalid) ...
marci@379: //(invalid, 1, vmi)
marci@379: //(invalid, 2, vmi)
marci@379: //invalid, 3, invalid)
marci@379:     template <typename T> class NodeMap;
marci@409:     template <typename T, typename Parent> class EdgeMap;
marci@341: 
marci@379: //    template <typename T> friend class NodeMap;
marci@379: //    template <typename T> friend class EdgeMap;
marci@341: 
marci@379:     const Node S_NODE;
marci@379:     const Node T_NODE;
marci@341: 
marci@379:     static const bool S_CLASS=false;
marci@379:     static const bool T_CLASS=true;
marci@341: 
marci@379:     stGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) , 
marci@379: 				    S_NODE(INVALID, 1), 
marci@379: 				    T_NODE(INVALID, 2) { }
marci@341: 
marci@435:     
marci@435: //    std::ostream& 
marci@435: //    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
marci@435: //    friend std::ostream& 
marci@435: //    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
marci@435: //    friend std::ostream& 
marci@435: //    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i);
marci@435: 
marci@379:     class Node : public Graph::Node {
marci@379:     protected:
marci@379:       friend class GraphWrapper<Graph>;
marci@379:       friend class stGraphWrapper<Graph>;
marci@389:       template <typename T> friend class NodeMap;
marci@380:       friend class Edge;
marci@380:       friend class OutEdgeIt;
marci@380:       friend class InEdgeIt;
marci@380:       friend class EdgeIt;
marci@379:       int spec; 
marci@379:     public:
marci@379:       Node() { }
marci@379:       Node(const typename Graph::Node& _n, int _spec=0) : 
marci@379: 	Graph::Node(_n), spec(_spec) { }
marci@379:       Node(const Invalid& i) : Graph::Node(i), spec(3) { }
marci@379:       friend bool operator==(const Node& u, const Node& v) { 
marci@379: 	return (u.spec==v.spec && 
marci@379: 		static_cast<typename Graph::Node>(u)==
marci@379: 		static_cast<typename Graph::Node>(v));
marci@379:       } 
marci@379:       friend bool operator!=(const Node& u, const Node& v) { 
marci@379: 	return (v.spec!=u.spec || 
marci@379: 		static_cast<typename Graph::Node>(u)!=
marci@379: 		static_cast<typename Graph::Node>(v));
marci@409:       }
marci@435: //      template<typename G> 
marci@435: //      friend std::ostream& 
marci@435: //      operator<<(std::ostream& os, const typename stGraphWrapper<G>::Node& i); 
marci@435:       friend std::ostream& operator<< (std::ostream& os, const Node& i);
marci@379:       int getSpec() const { return spec; }
marci@379:     };
marci@409: 
marci@379:     class NodeIt { 
marci@379:       friend class GraphWrapper<Graph>;
marci@379:       friend class stGraphWrapper<Graph>;
marci@379:       typename Graph::NodeIt n;
marci@379:       int spec; 
marci@379:      public:
marci@379:       NodeIt() { }
marci@379:       NodeIt(const typename Graph::NodeIt& _n, int _spec) : 
marci@379: 	n(_n), spec(_spec) { }
marci@379:       NodeIt(const Invalid& i) : n(i), spec(3) { }
marci@381:       NodeIt(const stGraphWrapper<Graph>& _G) : n(*(_G.graph)), spec(0) { 
marci@409: 	if (!_G.graph->valid(n)) spec=1;
marci@379:       }
marci@379:       operator Node() const { return Node(n, spec); }
marci@379:     };
marci@409: 
marci@379:     class Edge : public Graph::Edge {
marci@379:       friend class GraphWrapper<Graph>;
marci@379:       friend class stGraphWrapper<Graph>;
marci@409:       template <typename T, typename Parent> friend class EdgeMap;
marci@379:       int spec;
marci@379:       typename Graph::Node n;
marci@379:     public:
marci@379:       Edge() { }
marci@379:       Edge(const typename Graph::Edge& _e, int _spec, 
marci@379: 	   const typename Graph::Node& _n) : 
marci@379: 	Graph::Edge(_e), spec(_spec), n(_n) { 
marci@379:       }
marci@379:       Edge(const Invalid& i) : Graph::Edge(i), spec(3), n(i) { }
marci@379:       friend bool operator==(const Edge& u, const Edge& v) { 
marci@379: 	return (u.spec==v.spec && 
marci@379: 		static_cast<typename Graph::Edge>(u)==
marci@379: 		static_cast<typename Graph::Edge>(v) && 
marci@379: 		u.n==v.n);
marci@379:       } 
marci@379:       friend bool operator!=(const Edge& u, const Edge& v) { 
marci@379: 	return (v.spec!=u.spec || 
marci@379: 		static_cast<typename Graph::Edge>(u)!=
marci@379: 		static_cast<typename Graph::Edge>(v) || 
marci@379: 		u.n!=v.n);
marci@379:       } 
marci@435: //      template<typename G> 
marci@435: //      friend std::ostream& 
marci@435: //      operator<<(std::ostream& os, const typename stGraphWrapper<G>::Edge& i); 
marci@435:       friend std::ostream& operator<< (std::ostream& os, const Edge& i);
marci@379:       int getSpec() const { return spec; }
marci@379:     };
marci@409: 
marci@379:     class OutEdgeIt { 
marci@379:       friend class GraphWrapper<Graph>;
marci@379:       friend class stGraphWrapper<Graph>;
marci@379:       typename Graph::OutEdgeIt e;
marci@379:       int spec;
marci@379:       typename Graph::ClassNodeIt n;
marci@379:     public:
marci@379:       OutEdgeIt() { }
marci@379:       OutEdgeIt(const typename Graph::OutEdgeIt& _e, int _spec, 
marci@379: 		const typename Graph::ClassNodeIt& _n) : 
marci@379: 	e(_e), spec(_spec), n(_n) { 
marci@379:       }
marci@379:       OutEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
marci@381:       OutEdgeIt(const stGraphWrapper<Graph>& _G, const Node& _n) {
marci@379: 	switch (_n.spec) {
marci@379: 	  case 0 : 
marci@381: 	    if (_G.graph->inSClass(_n)) { //S, van normalis kiel 
marci@379: 	      e=typename Graph::OutEdgeIt(*(_G.graph), 
marci@379: 					  typename Graph::Node(_n)); 
marci@379: 	      spec=0;
marci@379: 	      n=INVALID;
marci@379: 	      if (!_G.graph->valid(e)) spec=3;
marci@379: 	    } else { //T, specko kiel van
marci@379: 	      e=INVALID;
marci@379: 	      spec=2;
marci@379: 	      n=_n;
marci@379: 	    }
marci@379: 	    break;
marci@379: 	  case 1:
marci@379: 	    e=INVALID;
marci@379: 	    spec=1;
marci@379: 	    _G.graph->first(n, S_CLASS); //s->vmi;
marci@379: 	    if (!_G.graph->valid(n)) spec=3; //Ha S ures
marci@379: 	    break;
marci@379: 	  case 2:
marci@379: 	    e=INVALID;
marci@379: 	    spec=3;
marci@379: 	    n=INVALID;
marci@379: 	    break;
marci@379: 	}
marci@379:       }
marci@379:       operator Edge() const { return Edge(e, spec, n); }
marci@379:     };
marci@409: 
marci@379:     class InEdgeIt { 
marci@379:       friend class GraphWrapper<Graph>;
marci@379:       friend class stGraphWrapper<Graph>;
marci@379:       typename Graph::InEdgeIt e;
marci@379:       int spec;
marci@379:       typename Graph::ClassNodeIt n;
marci@379:     public:
marci@379:       InEdgeIt() { }
marci@379:       InEdgeIt(const typename Graph::InEdgeIt& _e, int _spec, 
marci@379: 	       const typename Graph::ClassNodeIt& _n) : 
marci@379: 	e(_e), spec(_spec), n(_n) { 
marci@379:       }
marci@379:       InEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
marci@381:       InEdgeIt(const stGraphWrapper<Graph>& _G, const Node& _n) {
marci@379: 	switch (_n.spec) {
marci@379: 	  case 0 : 
marci@381: 	    if (_G.graph->inTClass(_n)) { //T, van normalis beel 
marci@379: 	      e=typename Graph::InEdgeIt(*(_G.graph), 
marci@379: 					 typename Graph::Node(_n)); 
marci@379: 	      spec=0;
marci@379: 	      n=INVALID;
marci@379: 	      if (!_G.graph->valid(e)) spec=3;
marci@379: 	    } else { //S, specko beel van
marci@379: 	      e=INVALID;
marci@379: 	      spec=1;
marci@379: 	      n=_n;
marci@379: 	    }
marci@379: 	    break;
marci@379: 	  case 1:
marci@379: 	    e=INVALID;
marci@379: 	    spec=3;
marci@379: 	    n=INVALID;
marci@409: 	    break;
marci@379: 	  case 2:
marci@379: 	    e=INVALID;
marci@409: 	    spec=2;
marci@379: 	    _G.graph->first(n, T_CLASS); //vmi->t;
marci@379: 	    if (!_G.graph->valid(n)) spec=3; //Ha T ures
marci@379: 	    break;
marci@379: 	}
marci@379:       }
marci@379:       operator Edge() const { return Edge(e, spec, n); }
marci@379:     };
marci@409: 
marci@379:     class EdgeIt { 
marci@379:       friend class GraphWrapper<Graph>;
marci@379:       friend class stGraphWrapper<Graph>;
marci@379:       typename Graph::EdgeIt e;
marci@379:       int spec;
marci@379:       typename Graph::ClassNodeIt n;
marci@379:     public:
marci@379:       EdgeIt() { }
marci@379:       EdgeIt(const typename Graph::EdgeIt& _e, int _spec, 
marci@379: 	     const typename Graph::ClassNodeIt& _n) : 
marci@379: 	e(_e), spec(_spec), n(_n) { }
marci@379:       EdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
marci@381:       EdgeIt(const stGraphWrapper<Graph>& _G) : 
marci@379: 	e(*(_G.graph)), spec(0), n(INVALID) { 
marci@379: 	if (!_G.graph->valid(e)) {
marci@379: 	  spec=1;
marci@379: 	  _G.graph->first(n, S_CLASS);
marci@379: 	  if (!_G.graph->valid(n)) { //Ha S ures
marci@379: 	    spec=2;
marci@379: 	    _G.graph->first(n, T_CLASS);
marci@379: 	    if (!_G.graph->valid(n)) { //Ha T ures
marci@379: 	      spec=3;
marci@379: 	    }
marci@379: 	  }
marci@379: 	}
marci@379:       }
marci@379:       operator Edge() const { return Edge(e, spec, n); }
marci@379:     };
marci@341:    
marci@379:     NodeIt& first(NodeIt& i) const { 
marci@379:       i=NodeIt(*this); return i;
marci@379:     }
marci@379:     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@379:       i=OutEdgeIt(*this, p); return i;
marci@379:     }
marci@379:     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@379:       i=InEdgeIt(*this, p); return i;
marci@379:     }
marci@379:     EdgeIt& first(EdgeIt& i) const { 
marci@379:       i=EdgeIt(*this); return i;
marci@379:     }
marci@341: 
marci@379:     NodeIt& next(NodeIt& i) const { 
marci@379:       switch (i.spec) {
marci@379: 	case 0:
marci@389: 	  this->graph->next(i.n);
marci@389: 	  if (!this->graph->valid(i.n)) {
marci@379: 	    i.spec=1;
marci@379: 	  }
marci@379: 	  break;
marci@379: 	case 1:
marci@379: 	  i.spec=2;
marci@379: 	  break;
marci@379: 	case 2:
marci@379: 	  i.spec=3;
marci@379: 	  break;
marci@379:       }
marci@379:       return i; 
marci@379:     }
marci@379:     OutEdgeIt& next(OutEdgeIt& i) const { 
marci@393:       typename Graph::Node v;
marci@379:       switch (i.spec) {
marci@379: 	case 0: //normal edge
marci@409: 	  v=this->graph->aNode(i.e);
marci@389: 	  this->graph->next(i.e);
marci@389: 	  if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
marci@389: 	    if (this->graph->inSClass(v)) { //S, nincs kiel
marci@379: 	      i.spec=3;
marci@379: 	      i.n=INVALID;
marci@379: 	    } else { //T, van kiel
marci@379: 	      i.spec=2; 
marci@379: 	      i.n=v;
marci@379: 	    }
marci@379: 	  }
marci@379: 	  break;
marci@379: 	case 1: //s->vmi
marci@389: 	  this->graph->next(i.n);
marci@389: 	  if (!this->graph->valid(i.n)) i.spec=3;
marci@379: 	  break;
marci@379: 	case 2: //vmi->t
marci@379: 	  i.spec=3;
marci@379: 	  i.n=INVALID;
marci@379: 	  break;
marci@379:       }
marci@379:       return i; 
marci@379:     }
marci@379:     InEdgeIt& next(InEdgeIt& i) const { 
marci@393:       typename Graph::Node v;
marci@379:       switch (i.spec) {
marci@379: 	case 0: //normal edge
marci@393: 	  v=this->graph->aNode(i.e);
marci@389: 	  this->graph->next(i.e);
marci@389: 	  if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
marci@389: 	    if (this->graph->inTClass(v)) { //S, nincs beel
marci@379: 	      i.spec=3;
marci@379: 	      i.n=INVALID;
marci@379: 	    } else { //S, van beel
marci@379: 	      i.spec=1; 
marci@379: 	      i.n=v;
marci@379: 	    }
marci@379: 	  }
marci@379: 	  break;
marci@379: 	case 1: //s->vmi
marci@379: 	  i.spec=3;
marci@379: 	  i.n=INVALID;
marci@379: 	  break;
marci@379: 	case 2: //vmi->t
marci@389: 	  this->graph->next(i.n);
marci@389: 	  if (!this->graph->valid(i.n)) i.spec=3;
marci@379: 	  break;
marci@379:       }
marci@379:       return i; 
marci@379:     }
marci@341: 
marci@379:     EdgeIt& next(EdgeIt& i) const { 
marci@379:       switch (i.spec) {
marci@379: 	case 0:
marci@389: 	  this->graph->next(i.e);
marci@389: 	  if (!this->graph->valid(i.e)) { 
marci@379: 	    i.spec=1;
marci@389: 	    this->graph->first(i.n, S_CLASS);
marci@389: 	    if (!this->graph->valid(i.n)) {
marci@379: 	      i.spec=2;
marci@389: 	      this->graph->first(i.n, T_CLASS);
marci@389: 	      if (!this->graph->valid(i.n)) i.spec=3;
marci@379: 	    }
marci@379: 	  }
marci@379: 	  break;
marci@379: 	case 1:
marci@389: 	  this->graph->next(i.n);
marci@389: 	  if (!this->graph->valid(i.n)) {
marci@379: 	    i.spec=2;
marci@389: 	    this->graph->first(i.n, T_CLASS);
marci@389: 	    if (!this->graph->valid(i.n)) i.spec=3;
marci@379: 	  }
marci@379: 	  break;
marci@379: 	case 2:
marci@389: 	  this->graph->next(i.n);
marci@389: 	  if (!this->graph->valid(i.n)) i.spec=3;
marci@379: 	  break;
marci@379:       }
marci@379:       return i; 
marci@379:     }    
marci@341: 
marci@379:     Node tail(const Edge& e) const { 
marci@379:       switch (e.spec) {
marci@393:       case 0: 
marci@393: 	return Node(this->graph->tail(e));
marci@393: 	break;
marci@393:       case 1:
marci@393: 	return S_NODE;
marci@393: 	break;
marci@393:       case 2:
marci@393:       default:
marci@393: 	return Node(e.n);
marci@393: 	break;
marci@379:       }
marci@379:     }
marci@379:     Node head(const Edge& e) const { 
marci@379:       switch (e.spec) {
marci@393:       case 0: 
marci@393: 	return Node(this->graph->head(e));
marci@393: 	break;
marci@393:       case 1:
marci@393: 	return Node(e.n);
marci@393: 	break;
marci@393:       case 2:
marci@393:       default:
marci@393: 	return T_NODE;
marci@393: 	break;
marci@379:       }
marci@379:     }
marci@341: 
marci@379:     bool valid(const Node& n) const { return (n.spec<3); }
marci@379:     bool valid(const Edge& e) const { return (e.spec<3); }
marci@379: 
marci@409:     int nodeNum() const { return this->graph->nodeNum()+2; }
marci@409:     int edgeNum() const { 
marci@409:       return this->graph->edgeNum()+this->graph->nodeNum(); 
marci@409:     }
marci@341:   
marci@379:     Node aNode(const OutEdgeIt& e) const { return tail(e); }
marci@379:     Node aNode(const InEdgeIt& e) const { return head(e); }
marci@379:     Node bNode(const OutEdgeIt& e) const { return head(e); }
marci@379:     Node bNode(const InEdgeIt& e) const { return tail(e); }
marci@409: 
marci@409:     void addNode() const { }
marci@409:     void addEdge() const { }
marci@409:     
marci@389: //    Node addNode() const { return Node(this->graph->addNode()); }
marci@379: //    Edge addEdge(const Node& tail, const Node& head) const { 
marci@389: //      return Edge(this->graph->addEdge(tail, head)); }
marci@341: 
marci@389: //    void erase(const Node& i) const { this->graph->erase(i); }
marci@389: //    void erase(const Edge& i) const { this->graph->erase(i); }
marci@341:   
marci@389: //    void clear() const { this->graph->clear(); }
marci@341:     
marci@389:     template<typename T> class NodeMap : public GraphWrapper<Graph>::template NodeMap<T> { 
marci@389:       typedef typename GraphWrapper<Graph>::template NodeMap<T> Parent;
marci@379:       T s_value, t_value;
marci@379:     public:
marci@409:       NodeMap(const stGraphWrapper<Graph>& _G) :  Parent(_G), 
marci@409: 						  s_value(), 
marci@409: 						  t_value() { }
marci@389:       NodeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a), 
marci@389: 						      s_value(a), 
marci@389: 						      t_value(a) { }
marci@379:       T operator[](const Node& n) const { 
marci@379: 	switch (n.spec) {
marci@393: 	case 0: 
marci@393: 	  return Parent::operator[](n);
marci@393: 	  break;
marci@393: 	case 1:
marci@393: 	  return s_value;
marci@393: 	  break;
marci@393: 	case 2: 
marci@393: 	default:
marci@393: 	  return t_value;
marci@393: 	  break;
marci@379: 	}
marci@379:       }
marci@379:       void set(const Node& n, T t) { 
marci@379: 	switch (n.spec) {
marci@393: 	case 0: 
marci@393: 	  GraphWrapper<Graph>::template NodeMap<T>::set(n, t);
marci@393: 	  break;
marci@393: 	case 1:
marci@393: 	  s_value=t;
marci@393: 	  break;
marci@393: 	case 2:
marci@393: 	default:
marci@393: 	  t_value=t;
marci@393: 	  break;
marci@379: 	}
marci@379:       }
marci@379:     };
marci@341: 
marci@409:     template<typename T, 
marci@409: 	     typename Parent=
marci@409: 	     typename GraphWrapper<Graph>::template EdgeMap<T> > 
marci@409:     class EdgeMap : public Parent { 
marci@409:       //typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
marci@389:       typename GraphWrapper<Graph>::template NodeMap<T> node_value;
marci@379:     public:
marci@393:       EdgeMap(const stGraphWrapper<Graph>& _G) : Parent(_G), 
marci@393: 						 node_value(_G) { }
marci@389:       EdgeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a), 
marci@389: 						      node_value(_G, a) { }
marci@379:       T operator[](const Edge& e) const { 
marci@379: 	switch (e.spec) {
marci@393: 	case 0: 
marci@393: 	  return Parent::operator[](e);
marci@393: 	  break;
marci@393: 	case 1:
marci@393: 	  return node_value[e.n];
marci@393: 	  break;
marci@393: 	case 2:
marci@393: 	default:
marci@393: 	  return node_value[e.n];
marci@393: 	  break;
marci@379: 	}
marci@379:       }
marci@379:       void set(const Edge& e, T t) { 
marci@379: 	switch (e.spec) {
marci@393: 	case 0: 
marci@409: 	  Parent::set(e, t);
marci@393: 	  break;
marci@393: 	case 1:
marci@393: 	  node_value.set(e.n, t);
marci@393: 	  break;
marci@393: 	case 2:
marci@393: 	default:
marci@393: 	  node_value.set(e.n, t);
marci@393: 	  break;
marci@379: 	}
marci@379:       }
marci@379:     };
marci@409: 
marci@409: //     template<typename T> class EdgeMap : public GraphWrapper<Graph>::template EdgeMap<T> { 
marci@409: //       typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
marci@409: //       typename GraphWrapper<Graph>::template NodeMap<T> node_value;
marci@409: //     public:
marci@409: //       EdgeMap(const stGraphWrapper<Graph>& _G) : Parent(_G), 
marci@409: // 						 node_value(_G) { }
marci@409: //       EdgeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a), 
marci@409: // 						      node_value(_G, a) { }
marci@409: //       T operator[](const Edge& e) const { 
marci@409: // 	switch (e.spec) {
marci@409: // 	case 0: 
marci@409: // 	  return Parent::operator[](e);
marci@409: // 	  break;
marci@409: // 	case 1:
marci@409: // 	  return node_value[e.n];
marci@409: // 	  break;
marci@409: // 	case 2:
marci@409: // 	default:
marci@409: // 	  return node_value[e.n];
marci@409: // 	  break;
marci@409: // 	}
marci@409: //       }
marci@409: //       void set(const Edge& e, T t) { 
marci@409: // 	switch (e.spec) {
marci@409: // 	case 0: 
marci@409: // 	  GraphWrapper<Graph>::template EdgeMap<T>::set(e, t);
marci@409: // 	  break;
marci@409: // 	case 1:
marci@409: // 	  node_value.set(e.n, t);
marci@409: // 	  break;
marci@409: // 	case 2:
marci@409: // 	default:
marci@409: // 	  node_value.set(e.n, t);
marci@409: // 	  break;
marci@409: // 	}
marci@409: //       }
marci@409: //     };
marci@409: 
marci@435: //  template<typename G> 
marci@435:     friend std::ostream& 
marci@435:     operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i) { 
marci@409:       os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")"; 
marci@409:       return os; 
marci@409:     }
marci@435: //  template<typename G> 
marci@435:     friend std::ostream& 
marci@435:     operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i) { 
marci@409:       os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec << 
marci@409: 	" node: " << i.n << ")"; 
marci@409:       return os; 
marci@409:     }
marci@409: 
marci@379:   };
marci@379: 
alpar@406:   ///@}
marci@341: 
alpar@105: } //namespace hugo
marci@76: 
alpar@406: 
marci@259: #endif //HUGO_GRAPH_WRAPPER_H
marci@76: