[Lemon-commits] [lemon_svn] marci: r395 - hugo/trunk/src/work/marci/experiment

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:39:12 CET 2006


Author: marci
Date: Sat Apr  3 19:26:46 2004
New Revision: 395

Added:
   hugo/trunk/src/work/marci/experiment/
   hugo/trunk/src/work/marci/experiment/bfs_iterator.h
   hugo/trunk/src/work/marci/experiment/bfs_iterator_1.h
   hugo/trunk/src/work/marci/experiment/deref_vs_optimization
   hugo/trunk/src/work/marci/experiment/deref_vs_optimization_lenyeg
   hugo/trunk/src/work/marci/experiment/edmonds_karp.h
   hugo/trunk/src/work/marci/experiment/edmonds_karp_1.h
   hugo/trunk/src/work/marci/experiment/edmonds_karp_demo.cc
   hugo/trunk/src/work/marci/experiment/edmonds_karp_demo_1.cc
   hugo/trunk/src/work/marci/experiment/graph_wrapper.h
   hugo/trunk/src/work/marci/experiment/graph_wrapper_1.h
   hugo/trunk/src/work/marci/experiment/iterator_bfs_demo.cc
   hugo/trunk/src/work/marci/experiment/iterator_bfs_demo_1.cc
   hugo/trunk/src/work/marci/experiment/list_graph.h
   hugo/trunk/src/work/marci/experiment/makefile

Log:
One more experimental study about dereferation vs optimization


Added: hugo/trunk/src/work/marci/experiment/bfs_iterator.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/bfs_iterator.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,841 @@
+// -*- c++ -*-
+#ifndef HUGO_BFS_ITERATOR_H
+#define HUGO_BFS_ITERATOR_H
+
+#include <queue>
+#include <stack>
+#include <utility>
+#include <graph_wrapper.h>
+
+namespace hugo {
+
+//   template <typename Graph>
+//   struct bfs {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::NodeIt NodeIt;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     Node s;
+//     typename Graph::NodeMap<bool> reached;
+//     typename Graph::NodeMap<Edge> pred;
+//     typename Graph::NodeMap<int> dist;
+//     std::queue<Node> bfs_queue;
+//     bfs(Graph& _G, Node _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { 
+//       bfs_queue.push(s); 
+//       for(NodeIt i=G.template first<NodeIt>(); i.valid(); ++i) 
+// 	reached.set(i, false);
+//       reached.set(s, true);
+//       dist.set(s, 0); 
+//     }
+    
+//     void run() {
+//       while (!bfs_queue.empty()) {
+// 	Node v=bfs_queue.front();
+// 	OutEdgeIt e=G.template first<OutEdgeIt>(v);
+// 	bfs_queue.pop();
+// 	for( ; e.valid(); ++e) {
+// 	  Node w=G.bNode(e);
+// 	  std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl;
+// 	  if (!reached.get(w)) {
+// 	    std::cout << G.id(w) << " is newly reached :-)" << std::endl;
+// 	    bfs_queue.push(w);
+// 	    dist.set(w, dist.get(v)+1);
+// 	    pred.set(w, e);
+// 	    reached.set(w, true);
+// 	  } else {
+// 	    std::cout << G.id(w) << " is already reached" << std::endl;
+// 	  }
+// 	}
+//       }
+//     }
+//   };
+
+//   template <typename Graph> 
+//   struct bfs_visitor {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     bfs_visitor(Graph& _G) : G(_G) { }
+//     void at_previously_reached(OutEdgeIt& e) { 
+//       //Node v=G.aNode(e);
+//       Node w=G.bNode(e);
+//       std::cout << G.id(w) << " is already reached" << std::endl;
+//    }
+//     void at_newly_reached(OutEdgeIt& e) { 
+//       //Node v=G.aNode(e);
+//       Node w=G.bNode(e);
+//       std::cout << G.id(w) << " is newly reached :-)" << std::endl;
+//     }
+//   };
+
+//   template <typename Graph, typename ReachedMap, typename visitor_type>
+//   struct bfs_iterator {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     visitor_type& visitor;
+//     void process() {
+//       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       if (bfs_queue.empty()) return;
+//       OutEdgeIt e=bfs_queue.front();
+//       //Node v=G.aNode(e);
+//       Node w=G.bNode(e);
+//       if (!reached.get(w)) {
+// 	visitor.at_newly_reached(e);
+// 	bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	reached.set(w, true);
+//       } else {
+// 	visitor.at_previously_reached(e);
+//       }
+//     }
+//     bfs_iterator(Graph& _G, std::queue<OutEdgeIt>& _bfs_queue, ReachedMap& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { 
+//       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       valid();
+//     }
+//     bfs_iterator<Graph, ReachedMap, visitor_type>& operator++() { 
+//       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       //if (bfs_queue.empty()) return *this;
+//       if (!valid()) return *this;
+//       ++(bfs_queue.front());
+//       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       valid();
+//       return *this;
+//     }
+//     //void next() { 
+//     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//     //  if (bfs_queue.empty()) return;
+//     //  ++(bfs_queue.front());
+//     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//     //}
+//     bool valid() { 
+//       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       if (bfs_queue.empty()) return false; else return true;
+//     }
+//     //bool finished() { 
+//     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//     //  if (bfs_queue.empty()) return true; else return false;
+//     //}
+//     operator Edge () { return bfs_queue.front(); }
+
+//   };
+
+//   template <typename Graph, typename ReachedMap>
+//   struct bfs_iterator1 {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool _newly_reached;
+//     bfs_iterator1(Graph& _G, std::queue<OutEdgeIt>& _bfs_queue, ReachedMap& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       valid();
+//       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
+// 	OutEdgeIt e=bfs_queue.front();
+// 	Node w=G.bNode(e);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	  reached.set(w, true);
+// 	  _newly_reached=true;
+// 	} else {
+// 	  _newly_reached=false;
+// 	}
+//       }
+//     }
+//     bfs_iterator1<Graph, ReachedMap>& operator++() { 
+//       if (!valid()) return *this;
+//       ++(bfs_queue.front());
+//       valid();
+//       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
+// 	OutEdgeIt e=bfs_queue.front();
+// 	Node w=G.bNode(e);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	  reached.set(w, true);
+// 	  _newly_reached=true;
+// 	} else {
+// 	  _newly_reached=false;
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool valid() { 
+//       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       if (bfs_queue.empty()) return false; else return true;
+//     }
+//     operator OutEdgeIt() { return bfs_queue.front(); }
+//     //ize
+//     bool newly_reached() { return _newly_reached; }
+
+//   };
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct BfsIterator {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     BfsIterator(Graph& _G, 
+// 		std::queue<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       actual_edge=bfs_queue.front();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.firstOutEdge(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  b_node_newly_reached=false;
+// 	}
+//       }
+//     }
+//     BfsIterator<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (bfs_queue.front().valid()) { 
+// 	++(bfs_queue.front());
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.firstOutEdge(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.firstOutEdge(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsExamined() { return !(actual_edge.valid()); }
+//   };
+
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct DfsIterator {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::stack<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     DfsIterator(Graph& _G, 
+// 		std::stack<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       actual_edge=bfs_queue.top();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.firstOutEdge(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  ++(bfs_queue.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	bfs_queue.pop();
+//       }
+//     }
+//     DfsIterator<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       actual_edge=bfs_queue.top();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.firstOutEdge(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  ++(bfs_queue.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	bfs_queue.pop();
+//       }
+//       return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsExamined() { return !(actual_edge.valid()); }
+//   };
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct BfsIterator1 {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     BfsIterator1(Graph& _G, 
+// 		std::queue<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       actual_edge=bfs_queue.front();
+//       if (actual_edge.valid()) { 
+//       	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(OutEdgeIt(G, w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  b_node_newly_reached=false;
+// 	}
+//       }
+//     }
+//     void next() { 
+//       if (bfs_queue.front().valid()) { 
+// 	++(bfs_queue.front());
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(OutEdgeIt(G, w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(OutEdgeIt(G, w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       }
+//       //return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsExamined() { return !(actual_edge.valid()); }
+//   };
+
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct DfsIterator1 {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::stack<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     DfsIterator1(Graph& _G, 
+// 		std::stack<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       //actual_edge=bfs_queue.top();
+//       //if (actual_edge.valid()) { 
+//       //	Node w=G.bNode(actual_edge);
+//       //if (!reached.get(w)) {
+//       //  bfs_queue.push(OutEdgeIt(G, w));
+//       //  reached.set(w, true);
+//       //  b_node_newly_reached=true;
+//       //} else {
+//       //  ++(bfs_queue.top());
+//       //  b_node_newly_reached=false;
+//       //}
+//       //} else {
+//       //	bfs_queue.pop();
+//       //}
+//     }
+//     void next() { 
+//       actual_edge=bfs_queue.top();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(OutEdgeIt(G, w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  ++(bfs_queue.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	bfs_queue.pop();
+//       }
+//       //return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsLeaved() { return !(actual_edge.valid()); }
+//   };
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   class BfsIterator2 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::queue<OutEdgeIt> bfs_queue;
+//     ReachedMap reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//   public:
+//     BfsIterator2(const Graph& _G) : G(_G), reached(G, false) { }
+//     void pushAndSetReached(Node s) { 
+//       reached.set(s, true);
+//       if (bfs_queue.empty()) {
+// 	bfs_queue.push(G.template first<OutEdgeIt>(s));
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) { 
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	} //else {
+// 	//}
+//       } else {
+// 	bfs_queue.push(G.template first<OutEdgeIt>(s));
+//       }
+//     }
+//     BfsIterator2<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (bfs_queue.front().valid()) { 
+// 	++(bfs_queue.front());
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	if (!bfs_queue.empty()) {
+// 	  actual_edge=bfs_queue.front();
+// 	  if (actual_edge.valid()) {
+// 	    Node w=G.bNode(actual_edge);
+// 	    if (!reached.get(w)) {
+// 	      bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	      reached.set(w, true);
+// 	      b_node_newly_reached=true;
+// 	    } else {
+// 	      b_node_newly_reached=false;
+// 	    }
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return bfs_queue.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(actual_edge.valid()); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     const std::queue<OutEdgeIt>& getBfsQueue() const { return bfs_queue; }
+//  };
+
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   class BfsIterator3 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::queue< std::pair<Node, OutEdgeIt> > bfs_queue;
+//     ReachedMap reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//   public:
+//     BfsIterator3(const Graph& _G) : G(_G), reached(G, false) { }
+//     void pushAndSetReached(Node s) { 
+//       reached.set(s, true);
+//       if (bfs_queue.empty()) {
+// 	bfs_queue.push(std::pair<Node, OutEdgeIt>(s, G.template first<OutEdgeIt>(s)));
+// 	actual_edge=bfs_queue.front().second;
+// 	if (actual_edge.valid()) { 
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(std::pair<Node, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	} //else {
+// 	//}
+//       } else {
+// 	bfs_queue.push(std::pair<Node, OutEdgeIt>(s, G.template first<OutEdgeIt>(s)));
+//       }
+//     }
+//     BfsIterator3<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (bfs_queue.front().second.valid()) { 
+// 	++(bfs_queue.front().second);
+// 	actual_edge=bfs_queue.front().second;
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(std::pair<Node, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	if (!bfs_queue.empty()) {
+// 	  actual_edge=bfs_queue.front().second;
+// 	  if (actual_edge.valid()) {
+// 	    Node w=G.bNode(actual_edge);
+// 	    if (!reached.get(w)) {
+// 	      bfs_queue.push(std::pair<Node, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
+// 	      reached.set(w, true);
+// 	      b_node_newly_reached=true;
+// 	    } else {
+// 	      b_node_newly_reached=false;
+// 	    }
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return bfs_queue.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(actual_edge.valid()); }
+//     Node aNode() const { return bfs_queue.front().first; }
+//     Node bNode() const { return G.bNode(actual_edge); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     //const std::queue< std::pair<Node, OutEdgeIt> >& getBfsQueue() const { return bfs_queue; }
+//  };
+
+
+//   template <typename Graph, typename OutEdgeIt, 
+// 	    typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
+//   class BfsIterator4 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::queue<Node> bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     bool own_reached_map;
+//   public:
+//     BfsIterator4(const Graph& _G, ReachedMap& _reached) : 
+//       G(_G), reached(_reached), 
+//       own_reached_map(false) { }
+//     BfsIterator4(const Graph& _G) : 
+//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+//       own_reached_map(true) { }
+//     ~BfsIterator4() { if (own_reached_map) delete &reached; }
+//     void pushAndSetReached(Node s) { 
+//       //std::cout << "mimi" << &reached << std::endl;
+//       reached.set(s, true);
+//       //std::cout << "mumus" << std::endl;
+//       if (bfs_queue.empty()) {
+// 	//std::cout << "bibi1" << std::endl;
+// 	bfs_queue.push(s);
+// 	//std::cout << "zizi" << std::endl;
+// 	G./*getF*/first(actual_edge, s);
+// 	//std::cout << "kiki" << std::endl;
+// 	if (G.valid(actual_edge)/*.valid()*/) { 
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(w);
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	} 
+//       } else {
+// 	//std::cout << "bibi2" << std::endl;
+// 	bfs_queue.push(s);
+//       }
+//     }
+//     BfsIterator4<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (G.valid(actual_edge)/*.valid()*/) { 
+// 	/*++*/G.next(actual_edge);
+// 	if (G.valid(actual_edge)/*.valid()*/) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(w);
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	if (!bfs_queue.empty()) {
+// 	  G./*getF*/first(actual_edge, bfs_queue.front());
+// 	  if (G.valid(actual_edge)/*.valid()*/) {
+// 	    Node w=G.bNode(actual_edge);
+// 	    if (!reached.get(w)) {
+// 	      bfs_queue.push(w);
+// 	      reached.set(w, true);
+// 	      b_node_newly_reached=true;
+// 	    } else {
+// 	      b_node_newly_reached=false;
+// 	    }
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return bfs_queue.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
+//     Node aNode() const { return bfs_queue.front(); }
+//     Node bNode() const { return G.bNode(actual_edge); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
+//  };  
+
+
+  template <typename GraphWrapper, /*typename OutEdgeIt,*/ 
+	    typename ReachedMap/*=typename GraphWrapper::NodeMap<bool>*/ >
+  class BfsIterator5 {
+    typedef typename GraphWrapper::Node Node;
+    typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    GraphWrapper G;
+    std::queue<Node> bfs_queue;
+    ReachedMap& reached;
+    bool b_node_newly_reached;
+    OutEdgeIt actual_edge;
+    bool own_reached_map;
+  public:
+    BfsIterator5(const GraphWrapper& _G, ReachedMap& _reached) : 
+      G(_G), reached(_reached), 
+      own_reached_map(false) { }
+    BfsIterator5(const GraphWrapper& _G) : 
+      G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+      own_reached_map(true) { }
+//     BfsIterator5(const typename GraphWrapper::BaseGraph& _G, 
+// 		 ReachedMap& _reached) : 
+//       G(_G), reached(_reached), 
+//       own_reached_map(false) { }
+//     BfsIterator5(const typename GraphWrapper::BaseGraph& _G) : 
+//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+//       own_reached_map(true) { }
+    ~BfsIterator5() { if (own_reached_map) delete &reached; }
+    void pushAndSetReached(Node s) { 
+      reached.set(s, true);
+      if (bfs_queue.empty()) {
+	bfs_queue.push(s);
+	G./*getF*/first(actual_edge, s);
+	if (G.valid(actual_edge)/*.valid()*/) { 
+	  Node w=G.bNode(actual_edge);
+	  if (!reached.get(w)) {
+	    bfs_queue.push(w);
+	    reached.set(w, true);
+	    b_node_newly_reached=true;
+	  } else {
+	    b_node_newly_reached=false;
+	  }
+	} 
+      } else {
+	bfs_queue.push(s);
+      }
+    }
+    BfsIterator5<GraphWrapper, /*OutEdgeIt,*/ ReachedMap>& 
+    operator++() { 
+      if (G.valid(actual_edge)/*.valid()*/) { 
+	/*++*/G.next(actual_edge);
+	if (G.valid(actual_edge)/*.valid()*/) {
+	  Node w=G.bNode(actual_edge);
+	  if (!reached.get(w)) {
+	    bfs_queue.push(w);
+	    reached.set(w, true);
+	    b_node_newly_reached=true;
+	  } else {
+	    b_node_newly_reached=false;
+	  }
+	}
+      } else {
+	bfs_queue.pop(); 
+	if (!bfs_queue.empty()) {
+	  G./*getF*/first(actual_edge, bfs_queue.front());
+	  if (G.valid(actual_edge)/*.valid()*/) {
+	    Node w=G.bNode(actual_edge);
+	    if (!reached.get(w)) {
+	      bfs_queue.push(w);
+	      reached.set(w, true);
+	      b_node_newly_reached=true;
+	    } else {
+	      b_node_newly_reached=false;
+	    }
+	  }
+	}
+      }
+      return *this;
+    }
+    bool finished() const { return bfs_queue.empty(); }
+    operator OutEdgeIt () const { return actual_edge; }
+    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+    bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
+    Node aNode() const { return bfs_queue.front(); }
+    Node bNode() const { return G.bNode(actual_edge); }
+    const ReachedMap& getReachedMap() const { return reached; }
+    const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
+  };  
+
+//   template <typename Graph, typename OutEdgeIt, 
+// 	    typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
+//   class DfsIterator4 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::stack<OutEdgeIt> dfs_stack;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     Node actual_node;
+//     ReachedMap& reached;
+//     bool own_reached_map;
+//   public:
+//     DfsIterator4(const Graph& _G, ReachedMap& _reached) : 
+//       G(_G), reached(_reached), 
+//       own_reached_map(false) { }
+//     DfsIterator4(const Graph& _G) : 
+//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+//       own_reached_map(true) { }
+//     ~DfsIterator4() { if (own_reached_map) delete &reached; }
+//     void pushAndSetReached(Node s) { 
+//       actual_node=s;
+//       reached.set(s, true);
+//       dfs_stack.push(G.template first<OutEdgeIt>(s)); 
+//     }
+//     DfsIterator4<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       actual_edge=dfs_stack.top();
+//       //actual_node=G.aNode(actual_edge);
+//       if (G.valid(actual_edge)/*.valid()*/) { 
+// 	Node w=G.bNode(actual_edge);
+// 	actual_node=w;
+// 	if (!reached.get(w)) {
+// 	  dfs_stack.push(G.template first<OutEdgeIt>(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  actual_node=G.aNode(actual_edge);
+// 	  /*++*/G.next(dfs_stack.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	//actual_node=G.aNode(dfs_stack.top());
+// 	dfs_stack.pop();
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return dfs_stack.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
+//     Node aNode() const { return actual_node; /*FIXME*/}
+//     Node bNode() const { return G.bNode(actual_edge); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
+//   };
+
+  template <typename GraphWrapper, /*typename OutEdgeIt,*/ 
+	    typename ReachedMap/*=typename GraphWrapper::NodeMap<bool>*/ >
+  class DfsIterator5 {
+    typedef typename GraphWrapper::Node Node;
+    typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    GraphWrapper G;
+    std::stack<OutEdgeIt> dfs_stack;
+    bool b_node_newly_reached;
+    OutEdgeIt actual_edge;
+    Node actual_node;
+    ReachedMap& reached;
+    bool own_reached_map;
+  public:
+    DfsIterator5(const GraphWrapper& _G, ReachedMap& _reached) : 
+      G(_G), reached(_reached), 
+      own_reached_map(false) { }
+    DfsIterator5(const GraphWrapper& _G) : 
+      G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+      own_reached_map(true) { }
+    ~DfsIterator5() { if (own_reached_map) delete &reached; }
+    void pushAndSetReached(Node s) { 
+      actual_node=s;
+      reached.set(s, true);
+      OutEdgeIt e;
+      G.first(e, s);
+      dfs_stack.push(e); 
+    }
+    DfsIterator5<GraphWrapper, /*OutEdgeIt,*/ ReachedMap>& 
+    operator++() { 
+      actual_edge=dfs_stack.top();
+      //actual_node=G.aNode(actual_edge);
+      if (G.valid(actual_edge)/*.valid()*/) { 
+	Node w=G.bNode(actual_edge);
+	actual_node=w;
+	if (!reached.get(w)) {
+	  OutEdgeIt e;
+	  G.first(e, w);
+	  dfs_stack.push(e);
+	  reached.set(w, true);
+	  b_node_newly_reached=true;
+	} else {
+	  actual_node=G.aNode(actual_edge);
+	  /*++*/G.next(dfs_stack.top());
+	  b_node_newly_reached=false;
+	}
+      } else {
+	//actual_node=G.aNode(dfs_stack.top());
+	dfs_stack.pop();
+      }
+      return *this;
+    }
+    bool finished() const { return dfs_stack.empty(); }
+    operator OutEdgeIt () const { return actual_edge; }
+    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+    bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
+    Node aNode() const { return actual_node; /*FIXME*/}
+    Node bNode() const { return G.bNode(actual_edge); }
+    const ReachedMap& getReachedMap() const { return reached; }
+    const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
+  };
+
+
+
+} // namespace hugo
+
+#endif //HUGO_BFS_ITERATOR_H

Added: hugo/trunk/src/work/marci/experiment/bfs_iterator_1.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/bfs_iterator_1.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,841 @@
+// -*- c++ -*-
+#ifndef HUGO_BFS_ITERATOR_H
+#define HUGO_BFS_ITERATOR_H
+
+#include <queue>
+#include <stack>
+#include <utility>
+#include <graph_wrapper_1.h>
+
+namespace hugo {
+
+//   template <typename Graph>
+//   struct bfs {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::NodeIt NodeIt;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     Node s;
+//     typename Graph::NodeMap<bool> reached;
+//     typename Graph::NodeMap<Edge> pred;
+//     typename Graph::NodeMap<int> dist;
+//     std::queue<Node> bfs_queue;
+//     bfs(Graph& _G, Node _s) : G(_G), s(_s), reached(_G), pred(_G), dist(_G) { 
+//       bfs_queue.push(s); 
+//       for(NodeIt i=G.template first<NodeIt>(); i.valid(); ++i) 
+// 	reached.set(i, false);
+//       reached.set(s, true);
+//       dist.set(s, 0); 
+//     }
+    
+//     void run() {
+//       while (!bfs_queue.empty()) {
+// 	Node v=bfs_queue.front();
+// 	OutEdgeIt e=G.template first<OutEdgeIt>(v);
+// 	bfs_queue.pop();
+// 	for( ; e.valid(); ++e) {
+// 	  Node w=G.bNode(e);
+// 	  std::cout << "scan node " << G.id(w) << " from node " << G.id(v) << std::endl;
+// 	  if (!reached.get(w)) {
+// 	    std::cout << G.id(w) << " is newly reached :-)" << std::endl;
+// 	    bfs_queue.push(w);
+// 	    dist.set(w, dist.get(v)+1);
+// 	    pred.set(w, e);
+// 	    reached.set(w, true);
+// 	  } else {
+// 	    std::cout << G.id(w) << " is already reached" << std::endl;
+// 	  }
+// 	}
+//       }
+//     }
+//   };
+
+//   template <typename Graph> 
+//   struct bfs_visitor {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     bfs_visitor(Graph& _G) : G(_G) { }
+//     void at_previously_reached(OutEdgeIt& e) { 
+//       //Node v=G.aNode(e);
+//       Node w=G.bNode(e);
+//       std::cout << G.id(w) << " is already reached" << std::endl;
+//    }
+//     void at_newly_reached(OutEdgeIt& e) { 
+//       //Node v=G.aNode(e);
+//       Node w=G.bNode(e);
+//       std::cout << G.id(w) << " is newly reached :-)" << std::endl;
+//     }
+//   };
+
+//   template <typename Graph, typename ReachedMap, typename visitor_type>
+//   struct bfs_iterator {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     visitor_type& visitor;
+//     void process() {
+//       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       if (bfs_queue.empty()) return;
+//       OutEdgeIt e=bfs_queue.front();
+//       //Node v=G.aNode(e);
+//       Node w=G.bNode(e);
+//       if (!reached.get(w)) {
+// 	visitor.at_newly_reached(e);
+// 	bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	reached.set(w, true);
+//       } else {
+// 	visitor.at_previously_reached(e);
+//       }
+//     }
+//     bfs_iterator(Graph& _G, std::queue<OutEdgeIt>& _bfs_queue, ReachedMap& _reached, visitor_type& _visitor) : G(_G), bfs_queue(_bfs_queue), reached(_reached), visitor(_visitor) { 
+//       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       valid();
+//     }
+//     bfs_iterator<Graph, ReachedMap, visitor_type>& operator++() { 
+//       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       //if (bfs_queue.empty()) return *this;
+//       if (!valid()) return *this;
+//       ++(bfs_queue.front());
+//       //while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       valid();
+//       return *this;
+//     }
+//     //void next() { 
+//     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//     //  if (bfs_queue.empty()) return;
+//     //  ++(bfs_queue.front());
+//     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//     //}
+//     bool valid() { 
+//       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       if (bfs_queue.empty()) return false; else return true;
+//     }
+//     //bool finished() { 
+//     //  while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//     //  if (bfs_queue.empty()) return true; else return false;
+//     //}
+//     operator Edge () { return bfs_queue.front(); }
+
+//   };
+
+//   template <typename Graph, typename ReachedMap>
+//   struct bfs_iterator1 {
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool _newly_reached;
+//     bfs_iterator1(Graph& _G, std::queue<OutEdgeIt>& _bfs_queue, ReachedMap& _reached) : G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       valid();
+//       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
+// 	OutEdgeIt e=bfs_queue.front();
+// 	Node w=G.bNode(e);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	  reached.set(w, true);
+// 	  _newly_reached=true;
+// 	} else {
+// 	  _newly_reached=false;
+// 	}
+//       }
+//     }
+//     bfs_iterator1<Graph, ReachedMap>& operator++() { 
+//       if (!valid()) return *this;
+//       ++(bfs_queue.front());
+//       valid();
+//       if (!bfs_queue.empty() && bfs_queue.front().valid()) { 
+// 	OutEdgeIt e=bfs_queue.front();
+// 	Node w=G.bNode(e);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	  reached.set(w, true);
+// 	  _newly_reached=true;
+// 	} else {
+// 	  _newly_reached=false;
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool valid() { 
+//       while ( !bfs_queue.empty() && !bfs_queue.front().valid() ) { bfs_queue.pop(); } 
+//       if (bfs_queue.empty()) return false; else return true;
+//     }
+//     operator OutEdgeIt() { return bfs_queue.front(); }
+//     //ize
+//     bool newly_reached() { return _newly_reached; }
+
+//   };
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct BfsIterator {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     BfsIterator(Graph& _G, 
+// 		std::queue<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       actual_edge=bfs_queue.front();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.firstOutEdge(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  b_node_newly_reached=false;
+// 	}
+//       }
+//     }
+//     BfsIterator<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (bfs_queue.front().valid()) { 
+// 	++(bfs_queue.front());
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.firstOutEdge(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.firstOutEdge(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsExamined() { return !(actual_edge.valid()); }
+//   };
+
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct DfsIterator {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::stack<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     DfsIterator(Graph& _G, 
+// 		std::stack<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       actual_edge=bfs_queue.top();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.firstOutEdge(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  ++(bfs_queue.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	bfs_queue.pop();
+//       }
+//     }
+//     DfsIterator<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       actual_edge=bfs_queue.top();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(G.firstOutEdge(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  ++(bfs_queue.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	bfs_queue.pop();
+//       }
+//       return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsExamined() { return !(actual_edge.valid()); }
+//   };
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct BfsIterator1 {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::queue<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     BfsIterator1(Graph& _G, 
+// 		std::queue<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       actual_edge=bfs_queue.front();
+//       if (actual_edge.valid()) { 
+//       	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(OutEdgeIt(G, w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  b_node_newly_reached=false;
+// 	}
+//       }
+//     }
+//     void next() { 
+//       if (bfs_queue.front().valid()) { 
+// 	++(bfs_queue.front());
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(OutEdgeIt(G, w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(OutEdgeIt(G, w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       }
+//       //return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsExamined() { return !(actual_edge.valid()); }
+//   };
+
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   struct DfsIterator1 {
+//     typedef typename Graph::Node Node;
+//     Graph& G;
+//     std::stack<OutEdgeIt>& bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     DfsIterator1(Graph& _G, 
+// 		std::stack<OutEdgeIt>& _bfs_queue, 
+// 		ReachedMap& _reached) : 
+//       G(_G), bfs_queue(_bfs_queue), reached(_reached) { 
+//       //actual_edge=bfs_queue.top();
+//       //if (actual_edge.valid()) { 
+//       //	Node w=G.bNode(actual_edge);
+//       //if (!reached.get(w)) {
+//       //  bfs_queue.push(OutEdgeIt(G, w));
+//       //  reached.set(w, true);
+//       //  b_node_newly_reached=true;
+//       //} else {
+//       //  ++(bfs_queue.top());
+//       //  b_node_newly_reached=false;
+//       //}
+//       //} else {
+//       //	bfs_queue.pop();
+//       //}
+//     }
+//     void next() { 
+//       actual_edge=bfs_queue.top();
+//       if (actual_edge.valid()) { 
+// 	Node w=G.bNode(actual_edge);
+// 	if (!reached.get(w)) {
+// 	  bfs_queue.push(OutEdgeIt(G, w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  ++(bfs_queue.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	bfs_queue.pop();
+//       }
+//       //return *this;
+//     }
+//     bool finished() { return bfs_queue.empty(); }
+//     operator OutEdgeIt () { return actual_edge; }
+//     bool bNodeIsNewlyReached() { return b_node_newly_reached; }
+//     bool aNodeIsLeaved() { return !(actual_edge.valid()); }
+//   };
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   class BfsIterator2 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::queue<OutEdgeIt> bfs_queue;
+//     ReachedMap reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//   public:
+//     BfsIterator2(const Graph& _G) : G(_G), reached(G, false) { }
+//     void pushAndSetReached(Node s) { 
+//       reached.set(s, true);
+//       if (bfs_queue.empty()) {
+// 	bfs_queue.push(G.template first<OutEdgeIt>(s));
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) { 
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	} //else {
+// 	//}
+//       } else {
+// 	bfs_queue.push(G.template first<OutEdgeIt>(s));
+//       }
+//     }
+//     BfsIterator2<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (bfs_queue.front().valid()) { 
+// 	++(bfs_queue.front());
+// 	actual_edge=bfs_queue.front();
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	if (!bfs_queue.empty()) {
+// 	  actual_edge=bfs_queue.front();
+// 	  if (actual_edge.valid()) {
+// 	    Node w=G.bNode(actual_edge);
+// 	    if (!reached.get(w)) {
+// 	      bfs_queue.push(G.template first<OutEdgeIt>(w));
+// 	      reached.set(w, true);
+// 	      b_node_newly_reached=true;
+// 	    } else {
+// 	      b_node_newly_reached=false;
+// 	    }
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return bfs_queue.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(actual_edge.valid()); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     const std::queue<OutEdgeIt>& getBfsQueue() const { return bfs_queue; }
+//  };
+
+
+//   template <typename Graph, typename OutEdgeIt, typename ReachedMap>
+//   class BfsIterator3 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::queue< std::pair<Node, OutEdgeIt> > bfs_queue;
+//     ReachedMap reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//   public:
+//     BfsIterator3(const Graph& _G) : G(_G), reached(G, false) { }
+//     void pushAndSetReached(Node s) { 
+//       reached.set(s, true);
+//       if (bfs_queue.empty()) {
+// 	bfs_queue.push(std::pair<Node, OutEdgeIt>(s, G.template first<OutEdgeIt>(s)));
+// 	actual_edge=bfs_queue.front().second;
+// 	if (actual_edge.valid()) { 
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(std::pair<Node, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	} //else {
+// 	//}
+//       } else {
+// 	bfs_queue.push(std::pair<Node, OutEdgeIt>(s, G.template first<OutEdgeIt>(s)));
+//       }
+//     }
+//     BfsIterator3<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (bfs_queue.front().second.valid()) { 
+// 	++(bfs_queue.front().second);
+// 	actual_edge=bfs_queue.front().second;
+// 	if (actual_edge.valid()) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(std::pair<Node, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	if (!bfs_queue.empty()) {
+// 	  actual_edge=bfs_queue.front().second;
+// 	  if (actual_edge.valid()) {
+// 	    Node w=G.bNode(actual_edge);
+// 	    if (!reached.get(w)) {
+// 	      bfs_queue.push(std::pair<Node, OutEdgeIt>(w, G.template first<OutEdgeIt>(w)));
+// 	      reached.set(w, true);
+// 	      b_node_newly_reached=true;
+// 	    } else {
+// 	      b_node_newly_reached=false;
+// 	    }
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return bfs_queue.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(actual_edge.valid()); }
+//     Node aNode() const { return bfs_queue.front().first; }
+//     Node bNode() const { return G.bNode(actual_edge); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     //const std::queue< std::pair<Node, OutEdgeIt> >& getBfsQueue() const { return bfs_queue; }
+//  };
+
+
+//   template <typename Graph, typename OutEdgeIt, 
+// 	    typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
+//   class BfsIterator4 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::queue<Node> bfs_queue;
+//     ReachedMap& reached;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     bool own_reached_map;
+//   public:
+//     BfsIterator4(const Graph& _G, ReachedMap& _reached) : 
+//       G(_G), reached(_reached), 
+//       own_reached_map(false) { }
+//     BfsIterator4(const Graph& _G) : 
+//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+//       own_reached_map(true) { }
+//     ~BfsIterator4() { if (own_reached_map) delete &reached; }
+//     void pushAndSetReached(Node s) { 
+//       //std::cout << "mimi" << &reached << std::endl;
+//       reached.set(s, true);
+//       //std::cout << "mumus" << std::endl;
+//       if (bfs_queue.empty()) {
+// 	//std::cout << "bibi1" << std::endl;
+// 	bfs_queue.push(s);
+// 	//std::cout << "zizi" << std::endl;
+// 	G./*getF*/first(actual_edge, s);
+// 	//std::cout << "kiki" << std::endl;
+// 	if (G.valid(actual_edge)/*.valid()*/) { 
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(w);
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	} 
+//       } else {
+// 	//std::cout << "bibi2" << std::endl;
+// 	bfs_queue.push(s);
+//       }
+//     }
+//     BfsIterator4<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       if (G.valid(actual_edge)/*.valid()*/) { 
+// 	/*++*/G.next(actual_edge);
+// 	if (G.valid(actual_edge)/*.valid()*/) {
+// 	  Node w=G.bNode(actual_edge);
+// 	  if (!reached.get(w)) {
+// 	    bfs_queue.push(w);
+// 	    reached.set(w, true);
+// 	    b_node_newly_reached=true;
+// 	  } else {
+// 	    b_node_newly_reached=false;
+// 	  }
+// 	}
+//       } else {
+// 	bfs_queue.pop(); 
+// 	if (!bfs_queue.empty()) {
+// 	  G./*getF*/first(actual_edge, bfs_queue.front());
+// 	  if (G.valid(actual_edge)/*.valid()*/) {
+// 	    Node w=G.bNode(actual_edge);
+// 	    if (!reached.get(w)) {
+// 	      bfs_queue.push(w);
+// 	      reached.set(w, true);
+// 	      b_node_newly_reached=true;
+// 	    } else {
+// 	      b_node_newly_reached=false;
+// 	    }
+// 	  }
+// 	}
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return bfs_queue.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
+//     Node aNode() const { return bfs_queue.front(); }
+//     Node bNode() const { return G.bNode(actual_edge); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
+//  };  
+
+
+  template <typename GraphWrapper, /*typename OutEdgeIt,*/ 
+	    typename ReachedMap/*=typename GraphWrapper::NodeMap<bool>*/ >
+  class BfsIterator5 {
+    typedef typename GraphWrapper::Node Node;
+    typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    const GraphWrapper* g;
+    std::queue<Node> bfs_queue;
+    ReachedMap& reached;
+    bool b_node_newly_reached;
+    OutEdgeIt actual_edge;
+    bool own_reached_map;
+  public:
+    BfsIterator5(const GraphWrapper& _g, ReachedMap& _reached) : 
+      g(&_g), reached(_reached), 
+      own_reached_map(false) { }
+    BfsIterator5(const GraphWrapper& _g) : 
+      g(&_g), reached(*(new ReachedMap(*g /*, false*/))), 
+      own_reached_map(true) { }
+//     BfsIterator5(const typename GraphWrapper::BaseGraph& _G, 
+// 		 ReachedMap& _reached) : 
+//       G(_G), reached(_reached), 
+//       own_reached_map(false) { }
+//     BfsIterator5(const typename GraphWrapper::BaseGraph& _G) : 
+//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+//       own_reached_map(true) { }
+    ~BfsIterator5() { if (own_reached_map) delete &reached; }
+    void pushAndSetReached(Node s) { 
+      reached.set(s, true);
+      if (bfs_queue.empty()) {
+	bfs_queue.push(s);
+	g->first(actual_edge, s);
+	if (g->valid(actual_edge)) { 
+	  Node w=g->bNode(actual_edge);
+	  if (!reached.get(w)) {
+	    bfs_queue.push(w);
+	    reached.set(w, true);
+	    b_node_newly_reached=true;
+	  } else {
+	    b_node_newly_reached=false;
+	  }
+	} 
+      } else {
+	bfs_queue.push(s);
+      }
+    }
+    BfsIterator5<GraphWrapper, /*OutEdgeIt,*/ ReachedMap>& 
+    operator++() { 
+      if (g->valid(actual_edge)) { 
+	g->next(actual_edge);
+	if (g->valid(actual_edge)) {
+	  Node w=g->bNode(actual_edge);
+	  if (!reached.get(w)) {
+	    bfs_queue.push(w);
+	    reached.set(w, true);
+	    b_node_newly_reached=true;
+	  } else {
+	    b_node_newly_reached=false;
+	  }
+	}
+      } else {
+	bfs_queue.pop(); 
+	if (!bfs_queue.empty()) {
+	  g->first(actual_edge, bfs_queue.front());
+	  if (g->valid(actual_edge)) {
+	    Node w=g->bNode(actual_edge);
+	    if (!reached.get(w)) {
+	      bfs_queue.push(w);
+	      reached.set(w, true);
+	      b_node_newly_reached=true;
+	    } else {
+	      b_node_newly_reached=false;
+	    }
+	  }
+	}
+      }
+      return *this;
+    }
+    bool finished() const { return bfs_queue.empty(); }
+    operator OutEdgeIt () const { return actual_edge; }
+    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+    bool isANodeExamined() const { return !(g->valid(actual_edge)); }
+    Node aNode() const { return bfs_queue.front(); }
+    Node bNode() const { return g->bNode(actual_edge); }
+    const ReachedMap& getReachedMap() const { return reached; }
+    const std::queue<Node>& getBfsQueue() const { return bfs_queue; }
+  };  
+
+//   template <typename Graph, typename OutEdgeIt, 
+// 	    typename ReachedMap/*=typename Graph::NodeMap<bool>*/ >
+//   class DfsIterator4 {
+//     typedef typename Graph::Node Node;
+//     const Graph& G;
+//     std::stack<OutEdgeIt> dfs_stack;
+//     bool b_node_newly_reached;
+//     OutEdgeIt actual_edge;
+//     Node actual_node;
+//     ReachedMap& reached;
+//     bool own_reached_map;
+//   public:
+//     DfsIterator4(const Graph& _G, ReachedMap& _reached) : 
+//       G(_G), reached(_reached), 
+//       own_reached_map(false) { }
+//     DfsIterator4(const Graph& _G) : 
+//       G(_G), reached(*(new ReachedMap(G /*, false*/))), 
+//       own_reached_map(true) { }
+//     ~DfsIterator4() { if (own_reached_map) delete &reached; }
+//     void pushAndSetReached(Node s) { 
+//       actual_node=s;
+//       reached.set(s, true);
+//       dfs_stack.push(G.template first<OutEdgeIt>(s)); 
+//     }
+//     DfsIterator4<Graph, OutEdgeIt, ReachedMap>& 
+//     operator++() { 
+//       actual_edge=dfs_stack.top();
+//       //actual_node=G.aNode(actual_edge);
+//       if (G.valid(actual_edge)/*.valid()*/) { 
+// 	Node w=G.bNode(actual_edge);
+// 	actual_node=w;
+// 	if (!reached.get(w)) {
+// 	  dfs_stack.push(G.template first<OutEdgeIt>(w));
+// 	  reached.set(w, true);
+// 	  b_node_newly_reached=true;
+// 	} else {
+// 	  actual_node=G.aNode(actual_edge);
+// 	  /*++*/G.next(dfs_stack.top());
+// 	  b_node_newly_reached=false;
+// 	}
+//       } else {
+// 	//actual_node=G.aNode(dfs_stack.top());
+// 	dfs_stack.pop();
+//       }
+//       return *this;
+//     }
+//     bool finished() const { return dfs_stack.empty(); }
+//     operator OutEdgeIt () const { return actual_edge; }
+//     bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+//     bool isANodeExamined() const { return !(G.valid(actual_edge)/*.valid()*/); }
+//     Node aNode() const { return actual_node; /*FIXME*/}
+//     Node bNode() const { return G.bNode(actual_edge); }
+//     const ReachedMap& getReachedMap() const { return reached; }
+//     const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
+//   };
+
+  template <typename GraphWrapper, /*typename OutEdgeIt,*/ 
+	    typename ReachedMap/*=typename GraphWrapper::NodeMap<bool>*/ >
+  class DfsIterator5 {
+    typedef typename GraphWrapper::Node Node;
+    typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    const GraphWrapper* g;
+    std::stack<OutEdgeIt> dfs_stack;
+    bool b_node_newly_reached;
+    OutEdgeIt actual_edge;
+    Node actual_node;
+    ReachedMap& reached;
+    bool own_reached_map;
+  public:
+    DfsIterator5(const GraphWrapper& _g, ReachedMap& _reached) : 
+      g(&_g), reached(_reached), 
+      own_reached_map(false) { }
+    DfsIterator5(const GraphWrapper& _g) : 
+      g(&_g), reached(*(new ReachedMap(*g /*, false*/))), 
+      own_reached_map(true) { }
+    ~DfsIterator5() { if (own_reached_map) delete &reached; }
+    void pushAndSetReached(Node s) { 
+      actual_node=s;
+      reached.set(s, true);
+      OutEdgeIt e;
+      g->first(e, s);
+      dfs_stack.push(e); 
+    }
+    DfsIterator5<GraphWrapper, /*OutEdgeIt,*/ ReachedMap>& 
+    operator++() { 
+      actual_edge=dfs_stack.top();
+      //actual_node=G.aNode(actual_edge);
+      if (g->valid(actual_edge)/*.valid()*/) { 
+	Node w=g->bNode(actual_edge);
+	actual_node=w;
+	if (!reached.get(w)) {
+	  OutEdgeIt e;
+	  g->first(e, w);
+	  dfs_stack.push(e);
+	  reached.set(w, true);
+	  b_node_newly_reached=true;
+	} else {
+	  actual_node=g->aNode(actual_edge);
+	  g->next(dfs_stack.top());
+	  b_node_newly_reached=false;
+	}
+      } else {
+	//actual_node=G.aNode(dfs_stack.top());
+	dfs_stack.pop();
+      }
+      return *this;
+    }
+    bool finished() const { return dfs_stack.empty(); }
+    operator OutEdgeIt () const { return actual_edge; }
+    bool isBNodeNewlyReached() const { return b_node_newly_reached; }
+    bool isANodeExamined() const { return !(g->valid(actual_edge)); }
+    Node aNode() const { return actual_node; /*FIXME*/}
+    Node bNode() const { return G.bNode(actual_edge); }
+    const ReachedMap& getReachedMap() const { return reached; }
+    const std::stack<OutEdgeIt>& getDfsStack() const { return dfs_stack; }
+  };
+
+
+
+} // namespace hugo
+
+#endif //HUGO_BFS_ITERATOR_H

Added: hugo/trunk/src/work/marci/experiment/deref_vs_optimization
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/deref_vs_optimization	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,147 @@
+-O0:
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 1.11s, s: 0.02s, cu: 0s, cs: 0s, real: 1.23456s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.78s, s: 0s, cu: 0s, cs: 0s, real: 0.851246s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 1.02s, s: 0s, cu: 0s, cs: 0s, real: 1.12829s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 76.09s, s: 0.77s, cu: 0s, cs: 0s, real: 127.892s
+number of augmentation phases: 1854
+flow value: 6068
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 1.04s, s: 0.01s, cu: 0s, cs: 0s, real: 1.1643s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.73s, s: 0s, cu: 0s, cs: 0s, real: 1.29574s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.96s, s: 0.01s, cu: 0s, cs: 0s, real: 1.05265s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 72.65s, s: 0.67s, cu: 0s, cs: 0s, real: 79.8199s
+number of augmentation phases: 1854
+flow value: 6068
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 3.04s, s: 0.01s, cu: 0s, cs: 0s, real: 3.09736s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 2.22s, s: 0.02s, cu: 0s, cs: 0s, real: 2.26504s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 2.88s, s: 0.01s, cu: 0s, cs: 0s, real: 3.03116s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 201.69s, s: 0.08s, cu: 0s, cs: 0s, real: 203.99s
+number of augmentation phases: 1854
+flow value: 6068
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 3s, s: 0.04s, cu: 0s, cs: 0s, real: 3.19728s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 2.21s, s: 0.03s, cu: 0s, cs: 0s, real: 2.25725s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 2.82s, s: 0s, cu: 0s, cs: 0s, real: 2.83294s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 203.39s, s: 0.07s, cu: 0s, cs: 0s, real: 204.401s
+number of augmentation phases: 1854
+flow value: 6068
+
+-03:
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.36s, s: 0.01s, cu: 0s, cs: 0s, real: 1.13854s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.23s, s: 0s, cu: 0s, cs: 0s, real: 0.243452s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.32s, s: 0.01s, cu: 0s, cs: 0s, real: 0.339224s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 26.98s, s: 0.29s, cu: 0s, cs: 0s, real: 32.2458s
+number of augmentation phases: 1854
+flow value: 6068
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.37s, s: 0.01s, cu: 0s, cs: 0s, real: 0.402523s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.22s, s: 0s, cu: 0s, cs: 0s, real: 0.244878s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.32s, s: 0.01s, cu: 0s, cs: 0s, real: 0.353093s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 27.02s, s: 0.34s, cu: 0s, cs: 0s, real: 30.0516s
+number of augmentation phases: 1854
+flow value: 6068
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.91s, s: 0.01s, cu: 0s, cs: 0s, real: 0.938415s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.61s, s: 0.01s, cu: 0s, cs: 0s, real: 0.62244s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.88s, s: 0s, cu: 0s, cs: 0s, real: 0.914984s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 66.55s, s: 0.09s, cu: 0s, cs: 0s, real: 67.5525s
+number of augmentation phases: 1854
+flow value: 6068
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.85s, s: 0s, cu: 0s, cs: 0s, real: 0.858786s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.58s, s: 0.03s, cu: 0s, cs: 0s, real: 0.61541s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.85s, s: 0s, cu: 0s, cs: 0s, real: 0.85847s
+number of augmentation phases: 3
+flow value: 6068
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 66.71s, s: 0.06s, cu: 0s, cs: 0s, real: 68.0292s
+number of augmentation phases: 1854
+flow value: 6068

Added: hugo/trunk/src/work/marci/experiment/deref_vs_optimization_lenyeg
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/deref_vs_optimization_lenyeg	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,83 @@
+-O0:
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 1.11s, s: 0.02s, cu: 0s, cs: 0s, real: 1.23456s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.78s, s: 0s, cu: 0s, cs: 0s, real: 0.851246s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 1.02s, s: 0s, cu: 0s, cs: 0s, real: 1.12829s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 76.09s, s: 0.77s, cu: 0s, cs: 0s, real: 127.892s
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 1.04s, s: 0.01s, cu: 0s, cs: 0s, real: 1.1643s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.73s, s: 0s, cu: 0s, cs: 0s, real: 1.29574s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.96s, s: 0.01s, cu: 0s, cs: 0s, real: 1.05265s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 72.65s, s: 0.67s, cu: 0s, cs: 0s, real: 79.8199s
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 3.04s, s: 0.01s, cu: 0s, cs: 0s, real: 3.09736s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 2.22s, s: 0.02s, cu: 0s, cs: 0s, real: 2.26504s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 2.88s, s: 0.01s, cu: 0s, cs: 0s, real: 3.03116s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 201.69s, s: 0.08s, cu: 0s, cs: 0s, real: 203.99s
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 3s, s: 0.04s, cu: 0s, cs: 0s, real: 3.19728s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 2.21s, s: 0.03s, cu: 0s, cs: 0s, real: 2.25725s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 2.82s, s: 0s, cu: 0s, cs: 0s, real: 2.83294s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 203.39s, s: 0.07s, cu: 0s, cs: 0s, real: 204.401s
+
+-03:
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.36s, s: 0.01s, cu: 0s, cs: 0s, real: 1.13854s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.23s, s: 0s, cu: 0s, cs: 0s, real: 0.243452s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.32s, s: 0.01s, cu: 0s, cs: 0s, real: 0.339224s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 26.98s, s: 0.29s, cu: 0s, cs: 0s, real: 32.2458s
+
+marci at karp:~/etik-ol/src/demo/marci/experiment$ ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.37s, s: 0.01s, cu: 0s, cs: 0s, real: 0.402523s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.22s, s: 0s, cu: 0s, cs: 0s, real: 0.244878s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.32s, s: 0.01s, cu: 0s, cs: 0s, real: 0.353093s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 27.02s, s: 0.34s, cu: 0s, cs: 0s, real: 30.0516s
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.91s, s: 0.01s, cu: 0s, cs: 0s, real: 0.938415s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.61s, s: 0.01s, cu: 0s, cs: 0s, real: 0.62244s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.88s, s: 0s, cu: 0s, cs: 0s, real: 0.914984s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 66.55s, s: 0.09s, cu: 0s, cs: 0s, real: 67.5525s
+
+marci at linux:~/etik-ol/src/demo/marci/experiment> ./edmonds_karp_demo_1 < ../flow-1.dim
+edmonds karp demo (physical blocking flow augmentation)...
+elapsed time: u: 0.85s, s: 0s, cu: 0s, cs: 0s, real: 0.858786s
+edmonds karp demo (physical blocking flow 1 augmentation)...
+elapsed time: u: 0.58s, s: 0.03s, cu: 0s, cs: 0s, real: 0.61541s
+edmonds karp demo (on-the-fly blocking flow augmentation)...
+elapsed time: u: 0.85s, s: 0s, cu: 0s, cs: 0s, real: 0.85847s
+edmonds karp demo (on-the-fly shortest path augmentation)...
+elapsed time: u: 66.71s, s: 0.06s, cu: 0s, cs: 0s, real: 68.0292s

Added: hugo/trunk/src/work/marci/experiment/edmonds_karp.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/edmonds_karp.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,1238 @@
+// -*- c++ -*-
+#ifndef HUGO_EDMONDS_KARP_H
+#define HUGO_EDMONDS_KARP_H
+
+#include <algorithm>
+#include <list>
+#include <iterator>
+
+#include <bfs_iterator.h>
+#include <invalid.h>
+
+namespace hugo {
+
+  template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+  class ResGraph {
+  public:
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+  private:
+    typedef typename Graph::SymEdgeIt OldSymEdgeIt;
+    const Graph& G;
+    FlowMap& flow;
+    const CapacityMap& capacity;
+  public:
+    ResGraph(const Graph& _G, FlowMap& _flow, 
+	     const CapacityMap& _capacity) : 
+      G(_G), flow(_flow), capacity(_capacity) { }
+
+    class Edge; 
+    class OutEdgeIt; 
+    friend class Edge; 
+    friend class OutEdgeIt; 
+
+    class Edge {
+      friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
+    protected:
+      const ResGraph<Graph, Number, FlowMap, CapacityMap>* resG;
+      OldSymEdgeIt sym;
+    public:
+      Edge() { } 
+      //Edge(const Edge& e) : resG(e.resG), sym(e.sym) { }
+      Number free() const { 
+	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
+	  return (resG->capacity.get(sym)-resG->flow.get(sym)); 
+	} else { 
+	  return (resG->flow.get(sym)); 
+	}
+      }
+      bool valid() const { return sym.valid(); }
+      void augment(Number a) const {
+	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
+	  resG->flow.set(sym, resG->flow.get(sym)+a);
+	  //resG->flow[sym]+=a;
+	} else { 
+	  resG->flow.set(sym, resG->flow.get(sym)-a);
+	  //resG->flow[sym]-=a;
+	}
+      }
+    };
+
+    class OutEdgeIt : public Edge {
+      friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
+    public:
+      OutEdgeIt() { }
+      //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
+    private:
+      OutEdgeIt(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
+      	resG=&_resG;
+	sym=resG->G.template first<OldSymEdgeIt>(v);
+	while( sym.valid() && !(free()>0) ) { ++sym; }
+      }
+    public:
+      OutEdgeIt& operator++() { 
+	++sym; 
+	while( sym.valid() && !(free()>0) ) { ++sym; }
+	return *this; 
+      }
+    };
+
+    void /*getF*/first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); 
+    }
+    void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
+    
+    template< typename It >
+    It first() const { 
+      It e;      
+      /*getF*/first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      /*getF*/first(e, v);
+      return e; 
+    }
+
+    Node tail(Edge e) const { return G.aNode(e.sym); }
+    Node head(Edge e) const { return G.bNode(e.sym); }
+
+    Node aNode(OutEdgeIt e) const { return G.aNode(e.sym); }
+    Node bNode(OutEdgeIt e) const { return G.bNode(e.sym); }
+
+    int id(Node v) const { return G.id(v); }
+
+    template <typename S>
+    class NodeMap {
+      typename Graph::NodeMap<S> node_map; 
+    public:
+      NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
+      NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
+      void set(Node nit, S a) { node_map.set(nit, a); }
+      S get(Node nit) const { return node_map.get(nit); }
+      S& operator[](Node nit) { return node_map[nit]; } 
+      const S& operator[](Node nit) const { return node_map[nit]; } 
+    };
+
+  };
+
+
+  template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+  class ResGraph2 {
+  public:
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+  private:
+    //typedef typename Graph::SymEdgeIt OldSymEdgeIt;
+    typedef typename Graph::OutEdgeIt OldOutEdgeIt;
+    typedef typename Graph::InEdgeIt OldInEdgeIt;
+    
+    const Graph& G;
+    FlowMap& flow;
+    const CapacityMap& capacity;
+  public:
+    ResGraph2(const Graph& _G, FlowMap& _flow, 
+	     const CapacityMap& _capacity) : 
+      G(_G), flow(_flow), capacity(_capacity) { }
+
+    class Edge; 
+    class OutEdgeIt; 
+    friend class Edge; 
+    friend class OutEdgeIt; 
+
+    class Edge {
+      friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
+    protected:
+      const ResGraph2<Graph, Number, FlowMap, CapacityMap>* resG;
+      //OldSymEdgeIt sym;
+      OldOutEdgeIt out;
+      OldInEdgeIt in;
+      bool out_or_in; //true, iff out
+    public:
+      Edge() : out_or_in(true) { } 
+      Number free() const { 
+	if (out_or_in) { 
+	  return (resG->capacity.get(out)-resG->flow.get(out)); 
+	} else { 
+	  return (resG->flow.get(in)); 
+	}
+      }
+      bool valid() const { 
+	return out_or_in && out.valid() || in.valid(); }
+      void augment(Number a) const {
+	if (out_or_in) { 
+	  resG->flow.set(out, resG->flow.get(out)+a);
+	} else { 
+	  resG->flow.set(in, resG->flow.get(in)-a);
+	}
+      }
+    };
+
+    class OutEdgeIt : public Edge {
+      friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
+    public:
+      OutEdgeIt() { }
+    private:
+      OutEdgeIt(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
+      	resG=&_resG;
+	out=resG->G.template first<OldOutEdgeIt>(v);
+	while( out.valid() && !(free()>0) ) { ++out; }
+	if (!out.valid()) {
+	  out_or_in=0;
+	  in=resG->G.template first<OldInEdgeIt>(v);
+	  while( in.valid() && !(free()>0) ) { ++in; }
+	}
+      }
+    public:
+      OutEdgeIt& operator++() { 
+	if (out_or_in) {
+	  Node v=resG->G.aNode(out);
+	  ++out;
+	  while( out.valid() && !(free()>0) ) { ++out; }
+	  if (!out.valid()) {
+	    out_or_in=0;
+	    in=resG->G.template first<OldInEdgeIt>(v);
+	    while( in.valid() && !(free()>0) ) { ++in; }
+	  }
+	} else {
+	  ++in;
+	  while( in.valid() && !(free()>0) ) { ++in; } 
+	}
+	return *this; 
+      }
+    };
+
+    void /*getF*/first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); 
+    }
+    void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
+    
+    template< typename It >
+    It first() const { 
+      It e;
+      /*getF*/first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      /*getF*/first(e, v);
+      return e; 
+    }
+
+    Node tail(Edge e) const { 
+      return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
+    Node head(Edge e) const { 
+      return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
+
+    Node aNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
+    Node bNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
+
+    int id(Node v) const { return G.id(v); }
+
+    template <typename S>
+    class NodeMap {
+      typename Graph::NodeMap<S> node_map; 
+    public:
+      NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
+      NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
+      void set(Node nit, S a) { node_map.set(nit, a); }
+      S get(Node nit) const { return node_map.get(nit); }
+    };
+  };
+
+
+  template <typename GraphWrapper, typename Number, typename FlowMap, typename CapacityMap>
+  class MaxFlow {
+  protected:
+    typedef GraphWrapper GW;
+    typedef typename GW::Node Node;
+    typedef typename GW::Edge Edge;
+    typedef typename GW::EdgeIt EdgeIt;
+    typedef typename GW::OutEdgeIt OutEdgeIt;
+    typedef typename GW::InEdgeIt InEdgeIt;
+    //const Graph* G;
+    GW gw;
+    Node s;
+    Node t;
+    FlowMap* flow;
+    const CapacityMap* capacity;
+    typedef ResGraphWrapper<GW, Number, FlowMap, CapacityMap > ResGW;
+    typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
+    typedef typename ResGW::Edge ResGWEdge;
+  public:
+
+    MaxFlow(const GW& _gw, Node _s, Node _t, FlowMap& _flow, const CapacityMap& _capacity) : 
+      gw(_gw), s(_s), t(_t), flow(&_flow), capacity(&_capacity) { }
+
+    bool augmentOnShortestPath() {
+      ResGW res_graph(gw, *flow, *capacity);
+      bool _augment=false;
+      
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+      bfs.pushAndSetReached(s);
+	
+      typename ResGW::NodeMap<ResGWEdge> pred(res_graph); 
+      pred.set(s, INVALID);
+      
+      typename ResGW::NodeMap<Number> free(res_graph);
+	
+      //searching for augmenting path
+      while ( !bfs.finished() ) { 
+	ResGWOutEdgeIt e=bfs;
+	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+	  Node v=res_graph.tail(e);
+	  Node w=res_graph.head(e);
+	  pred.set(w, e);
+	  if (res_graph.valid(pred.get(v))) {
+	    free.set(w, std::min(free.get(v), res_graph.resCap(e)));
+	  } else {
+	    free.set(w, res_graph.resCap(e)); 
+	  }
+	  if (res_graph.head(e)==t) { _augment=true; break; }
+	}
+	
+	++bfs;
+      } //end of searching augmenting path
+
+      if (_augment) {
+	Node n=t;
+	Number augment_value=free.get(t);
+	while (res_graph.valid(pred.get(n))) { 
+	  ResGWEdge e=pred.get(n);
+	  res_graph.augment(e, augment_value); 
+	  n=res_graph.tail(e);
+	}
+      }
+
+      return _augment;
+    }
+
+    template<typename MapGraphWrapper> 
+    class DistanceMap {
+    protected:
+      MapGraphWrapper gw;
+      typename MapGraphWrapper::NodeMap<int> dist; 
+    public:
+      DistanceMap(MapGraphWrapper& _gw) : gw(_gw), dist(_gw, _gw.nodeNum()) { }
+      void set(const typename MapGraphWrapper::Node& n, int a) { dist[n]=a; }
+      int get(const typename MapGraphWrapper::Node& n) const { return dist[n]; }
+      bool get(const typename MapGraphWrapper::Edge& e) const { 
+	return (dist.get(gw.tail(e))<dist.get(gw.head(e))); 
+      }
+    };
+
+    template<typename MutableGraph> bool augmentOnBlockingFlow() {      
+      typedef MutableGraph MG;
+      bool _augment=false;
+
+      ResGW res_graph(gw, *flow, *capacity);
+
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+
+      bfs.pushAndSetReached(s);
+      //typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
+      DistanceMap<ResGW> dist(res_graph);
+      while ( !bfs.finished() ) { 
+	ResGWOutEdgeIt e=bfs;
+	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+	}
+	++bfs;
+      } //computing distances from s in the residual graph
+
+      MG F;
+      typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
+      FilterResGW filter_res_graph(res_graph, dist);
+      typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
+      {
+	typename ResGW::NodeIt n;
+	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
+	  res_graph_to_F.set(n, F.addNode());
+	}
+      }
+
+      typename MG::Node sF=res_graph_to_F.get(s);
+      typename MG::Node tF=res_graph_to_F.get(t);
+      typename MG::EdgeMap<ResGWEdge> original_edge(F);
+      typename MG::EdgeMap<Number> residual_capacity(F);
+
+      //Making F to the graph containing the edges of the residual graph 
+      //which are in some shortest paths
+      {
+	typename FilterResGW::EdgeIt e;
+	for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) {
+	  //if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
+	  typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+	  original_edge.update();
+	  original_edge.set(f, e);
+	  residual_capacity.update();
+	  residual_capacity.set(f, res_graph.resCap(e));
+	  //} 
+	}
+      }
+
+      bool __augment=true;
+
+      while (__augment) {
+	__augment=false;
+	//computing blocking flow with dfs
+	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
+	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
+	typename MG::NodeMap<typename MG::Edge> pred(F);
+	pred.set(sF, INVALID);
+	//invalid iterators for sources
+
+	typename MG::NodeMap<Number> free(F);
+
+	dfs.pushAndSetReached(sF);      
+	while (!dfs.finished()) {
+	  ++dfs;
+	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
+	    if (dfs.isBNodeNewlyReached()) {
+	      typename MG::Node v=F.aNode(dfs);
+	      typename MG::Node w=F.bNode(dfs);
+	      pred.set(w, dfs);
+	      if (F.valid(pred.get(v))) {
+		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
+	      } else {
+		free.set(w, residual_capacity.get(dfs)); 
+	      }
+	      if (w==tF) { 
+		__augment=true; 
+		_augment=true;
+		break; 
+	      }
+	      
+	    } else {
+	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
+	    }
+	  } 
+	}
+
+	if (__augment) {
+	  typename MG::Node n=tF;
+	  Number augment_value=free.get(tF);
+	  while (F.valid(pred.get(n))) { 
+	    typename MG::Edge e=pred.get(n);
+	    res_graph.augment(original_edge.get(e), augment_value); 
+	    n=F.tail(e);
+	    if (residual_capacity.get(e)==augment_value) 
+	      F.erase(e); 
+	    else 
+	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
+	  }
+	}
+	
+      }
+            
+      return _augment;
+    }
+
+    template<typename MutableGraph> bool augmentOnBlockingFlow1() {      
+      typedef MutableGraph MG;
+      bool _augment=false;
+
+      ResGW res_graph(gw, *flow, *capacity);
+
+      //bfs for distances on the residual graph
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+      bfs.pushAndSetReached(s);
+      typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
+
+      //F will contain the physical copy of the residual graph
+      //with the set of edges which are on shortest paths
+      MG F;
+      typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
+      {
+	typename ResGW::NodeIt n;
+	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
+	  res_graph_to_F.set(n, F.addNode());
+	}
+      }
+
+      typename MG::Node sF=res_graph_to_F.get(s);
+      typename MG::Node tF=res_graph_to_F.get(t);
+      typename MG::EdgeMap<ResGWEdge> original_edge(F);
+      typename MG::EdgeMap<Number> residual_capacity(F);
+
+      while ( !bfs.finished() ) { 
+	ResGWOutEdgeIt e=bfs;
+	if (res_graph.valid(e)) {
+	  if (bfs.isBNodeNewlyReached()) {
+	    dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+	    typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+	    original_edge.update();
+	    original_edge.set(f, e);
+	    residual_capacity.update();
+	    residual_capacity.set(f, res_graph.resCap(e));
+	  } else {
+	    if (dist.get(res_graph.head(e))==(dist.get(res_graph.tail(e))+1)) {
+	      typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+	      original_edge.update();
+	      original_edge.set(f, e);
+	      residual_capacity.update();
+	      residual_capacity.set(f, res_graph.resCap(e));
+	    }
+	  }
+	}
+	++bfs;
+      } //computing distances from s in the residual graph
+
+      bool __augment=true;
+
+      while (__augment) {
+	__augment=false;
+	//computing blocking flow with dfs
+	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
+	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
+	typename MG::NodeMap<typename MG::Edge> pred(F);
+	pred.set(sF, INVALID);
+	//invalid iterators for sources
+
+	typename MG::NodeMap<Number> free(F);
+
+	dfs.pushAndSetReached(sF);      
+	while (!dfs.finished()) {
+	  ++dfs;
+	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
+	    if (dfs.isBNodeNewlyReached()) {
+	      typename MG::Node v=F.aNode(dfs);
+	      typename MG::Node w=F.bNode(dfs);
+	      pred.set(w, dfs);
+	      if (F.valid(pred.get(v))) {
+		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
+	      } else {
+		free.set(w, residual_capacity.get(dfs)); 
+	      }
+	      if (w==tF) { 
+		__augment=true; 
+		_augment=true;
+		break; 
+	      }
+	      
+	    } else {
+	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
+	    }
+	  } 
+	}
+
+	if (__augment) {
+	  typename MG::Node n=tF;
+	  Number augment_value=free.get(tF);
+	  while (F.valid(pred.get(n))) { 
+	    typename MG::Edge e=pred.get(n);
+	    res_graph.augment(original_edge.get(e), augment_value); 
+	    n=F.tail(e);
+	    if (residual_capacity.get(e)==augment_value) 
+	      F.erase(e); 
+	    else 
+	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
+	  }
+	}
+	
+      }
+            
+      return _augment;
+    }
+
+    bool augmentOnBlockingFlow2() {
+      bool _augment=false;
+
+      ResGW res_graph(gw, *flow, *capacity);
+
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+
+      bfs.pushAndSetReached(s);
+      DistanceMap<ResGW> dist(res_graph);
+      while ( !bfs.finished() ) { 
+ 	ResGWOutEdgeIt e=bfs;
+ 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+ 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+ 	}
+	++bfs;
+      } //computing distances from s in the residual graph
+
+      //Subgraph containing the edges on some shortest paths
+      typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
+      FilterResGW filter_res_graph(res_graph, dist);
+
+      //Subgraph, which is able to delete edges which are already 
+      //met by the dfs
+      typename FilterResGW::NodeMap<typename FilterResGW::OutEdgeIt> 
+ 	first_out_edges(filter_res_graph);
+      typename FilterResGW::NodeIt v;
+      for(filter_res_graph.first(v); filter_res_graph.valid(v); 
+ 	  filter_res_graph.next(v)) 
+      {
+ 	typename FilterResGW::OutEdgeIt e;
+ 	filter_res_graph.first(e, v);
+ 	first_out_edges.set(v, e);
+      }
+      typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
+	NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
+      ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
+
+      bool __augment=true;
+
+      while (__augment) {
+
+ 	__augment=false;
+ 	//computing blocking flow with dfs
+	typedef typename ErasingResGW::NodeMap<bool> BlockingReachedMap;
+ 	DfsIterator5< ErasingResGW, BlockingReachedMap > 
+ 	  dfs(erasing_res_graph);
+ 	typename ErasingResGW::NodeMap<typename ErasingResGW::OutEdgeIt> 
+ 	  pred(erasing_res_graph); 
+ 	pred.set(s, INVALID);
+ 	//invalid iterators for sources
+
+ 	typename ErasingResGW::NodeMap<Number> free(erasing_res_graph);
+
+ 	dfs.pushAndSetReached(s);
+ 	while (!dfs.finished()) {
+ 	  ++dfs;
+ 	  if (erasing_res_graph.valid(
+ 		/*typename ErasingResGW::OutEdgeIt*/(dfs))) 
+ 	  { 
+ 	    if (dfs.isBNodeNewlyReached()) {
+	  
+ 	      typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
+ 	      typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
+
+ 	      pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
+ 	      if (erasing_res_graph.valid(pred.get(v))) {
+ 		free.set(w, std::min(free.get(v), res_graph.resCap(dfs)));
+ 	      } else {
+ 		free.set(w, res_graph.resCap(dfs)); 
+ 	      }
+	      
+ 	      if (w==t) { 
+ 		__augment=true; 
+ 		_augment=true;
+ 		break; 
+ 	      }
+	    } else {
+	      erasing_res_graph.erase(dfs);
+	    }
+	  }
+	}	
+
+ 	if (__augment) {
+ 	  typename ErasingResGW::Node n=t;
+ 	  Number augment_value=free.get(n);
+ 	  while (erasing_res_graph.valid(pred.get(n))) { 
+ 	    typename ErasingResGW::OutEdgeIt e=pred.get(n);
+ 	    res_graph.augment(e, augment_value);
+ 	    n=erasing_res_graph.tail(e);
+ 	    if (res_graph.resCap(e)==0)
+ 	      erasing_res_graph.erase(e);
+ 	  }
+ 	}
+      
+      } //while (__augment) 
+            
+      return _augment;
+    }
+
+//     bool augmentOnBlockingFlow2() {
+//       bool _augment=false;
+
+//       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
+//       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
+//       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
+//       typedef typename EAugGraph::Edge EAugEdge;
+
+//       EAugGraph res_graph(*G, *flow, *capacity);
+
+//       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
+//       BfsIterator5< 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
+// 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
+      
+//       bfs.pushAndSetReached(s);
+
+//       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
+// 	NodeMap<int>& dist=res_graph.dist;
+
+//       while ( !bfs.finished() ) {
+// 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
+// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+// 	}
+// 	++bfs;	
+//       } //computing distances from s in the residual graph
+
+//       bool __augment=true;
+
+//       while (__augment) {
+
+// 	__augment=false;
+// 	//computing blocking flow with dfs
+// 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
+// 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
+// 	  dfs(res_graph);
+// 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph); 
+// 	pred.set(s, EAugEdge(INVALID));
+// 	//invalid iterators for sources
+
+// 	typename EAugGraph::NodeMap<Number> free(res_graph);
+
+// 	dfs.pushAndSetReached(s);
+// 	while (!dfs.finished()) {
+// 	  ++dfs;
+// 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
+// 	    if (dfs.isBNodeNewlyReached()) {
+	  
+// 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
+// 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
+
+// 	      pred.set(w, EAugOutEdgeIt(dfs));
+// 	      if (res_graph.valid(pred.get(v))) {
+// 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
+// 	      } else {
+// 		free.set(w, res_graph.free(dfs)); 
+// 	      }
+	      
+// 	      if (w==t) { 
+// 		__augment=true; 
+// 		_augment=true;
+// 		break; 
+// 	      }
+// 	    } else {
+// 	      res_graph.erase(dfs);
+// 	    }
+// 	  } 
+
+// 	}
+
+// 	if (__augment) {
+// 	  typename EAugGraph::Node n=t;
+// 	  Number augment_value=free.get(t);
+// 	  while (res_graph.valid(pred.get(n))) { 
+// 	    EAugEdge e=pred.get(n);
+// 	    res_graph.augment(e, augment_value);
+// 	    n=res_graph.tail(e);
+// 	    if (res_graph.free(e)==0)
+// 	      res_graph.erase(e);
+// 	  }
+// 	}
+      
+//       }
+            
+//       return _augment;
+//     }
+
+    void run() {
+      //int num_of_augmentations=0;
+      while (augmentOnShortestPath()) { 
+	//while (augmentOnBlockingFlow<MutableGraph>()) { 
+	//std::cout << ++num_of_augmentations << " ";
+	//std::cout<<std::endl;
+      } 
+    }
+
+    template<typename MutableGraph> void run() {
+      //int num_of_augmentations=0;
+      //while (augmentOnShortestPath()) { 
+	while (augmentOnBlockingFlow<MutableGraph>()) { 
+	//std::cout << ++num_of_augmentations << " ";
+	//std::cout<<std::endl;
+      } 
+    }
+
+    Number flowValue() { 
+      Number a=0;
+      OutEdgeIt e;
+      for(gw.first(e, s); gw.valid(e); gw.next(e)) {
+	a+=flow->get(e);
+      }
+      return a;
+    }
+
+  };
+
+
+//   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+//   class MaxMatching {
+//   public:
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::NodeIt NodeIt;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::EdgeIt EdgeIt;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     typedef typename Graph::InEdgeIt InEdgeIt;
+
+//     typedef typename Graph::NodeMap<bool> SMap;
+//     typedef typename Graph::NodeMap<bool> TMap;
+//   private:
+//     const Graph* G;
+//     SMap* S;
+//     TMap* T;
+//     //Node s;
+//     //Node t;
+//     FlowMap* flow;
+//     const CapacityMap* capacity;
+//     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
+//     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
+//     typedef typename AugGraph::Edge AugEdge;
+//     typename Graph::NodeMap<int> used; //0
+
+//   public:
+//     MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapacityMap& _capacity) : 
+//       G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { }
+//     bool augmentOnShortestPath() {
+//       AugGraph res_graph(*G, *flow, *capacity);
+//       bool _augment=false;
+      
+//       typedef typename AugGraph::NodeMap<bool> ReachedMap;
+//       BfsIterator5< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph);
+//       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// 	if ((S->get(s)) && (used.get(s)<1) ) {
+// 	  //Number u=0;
+// 	  //for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// 	  //u+=flow->get(e);
+// 	  //if (u<1) {
+// 	    bfs.pushAndSetReached(s);
+// 	    pred.set(s, AugEdge(INVALID));
+// 	    //}
+// 	}
+//       }
+      
+//       typename AugGraph::NodeMap<Number> free(res_graph);
+	
+//       Node n;
+//       //searching for augmenting path
+//       while ( !bfs.finished() ) { 
+// 	AugOutEdgeIt e=bfs;
+// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// 	  Node v=res_graph.tail(e);
+// 	  Node w=res_graph.head(e);
+// 	  pred.set(w, e);
+// 	  if (res_graph.valid(pred.get(v))) {
+// 	    free.set(w, std::min(free.get(v), res_graph.free(e)));
+// 	  } else {
+// 	    free.set(w, res_graph.free(e)); 
+// 	  }
+// 	  n=res_graph.head(e);
+// 	  if (T->get(n) && (used.get(n)<1) ) { 
+// 	    //Number u=0;
+// 	    //for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
+// 	    //u+=flow->get(f);
+// 	    //if (u<1) {
+// 	      _augment=true; 
+// 	      break; 
+// 	      //}
+// 	  }
+// 	}
+	
+// 	++bfs;
+//       } //end of searching augmenting path
+
+//       if (_augment) {
+// 	//Node n=t;
+// 	used.set(n, 1); //mind2 vegen jav
+// 	Number augment_value=free.get(n);
+// 	while (res_graph.valid(pred.get(n))) { 
+// 	  AugEdge e=pred.get(n);
+// 	  res_graph.augment(e, augment_value); 
+// 	  n=res_graph.tail(e);
+// 	}
+// 	used.set(n, 1); //mind2 vegen jav
+//       }
+
+//       return _augment;
+//     }
+
+// //     template<typename MutableGraph> bool augmentOnBlockingFlow() {      
+// //       bool _augment=false;
+
+// //       AugGraph res_graph(*G, *flow, *capacity);
+
+// //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
+// //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
+
+
+
+
+
+// //       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+// //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// // 	if (S->get(s)) {
+// // 	  Number u=0;
+// // 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// // 	    u+=flow->get(e);
+// // 	  if (u<1) {
+// // 	    bfs.pushAndSetReached(s);
+// // 	    //pred.set(s, AugEdge(INVALID));
+// // 	  }
+// // 	}
+// //       }
+
+
+
+
+// //       //bfs.pushAndSetReached(s);
+// //       typename AugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
+// //       while ( !bfs.finished() ) { 
+// // 	AugOutEdgeIt e=bfs;
+// // 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// // 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+// // 	}
+	
+// // 	++bfs;
+// //       } //computing distances from s in the residual graph
+
+// //       MutableGraph F;
+// //       typename AugGraph::NodeMap<typename MutableGraph::Node> 
+// // 	res_graph_to_F(res_graph);
+// //       for(typename AugGraph::NodeIt n=res_graph.template first<typename AugGraph::NodeIt>(); res_graph.valid(n); res_graph.next(n)) {
+// // 	res_graph_to_F.set(n, F.addNode());
+// //       }
+      
+// //       typename MutableGraph::Node sF=res_graph_to_F.get(s);
+// //       typename MutableGraph::Node tF=res_graph_to_F.get(t);
+
+// //       typename MutableGraph::EdgeMap<AugEdge> original_edge(F);
+// //       typename MutableGraph::EdgeMap<Number> residual_capacity(F);
+
+// //       //Making F to the graph containing the edges of the residual graph 
+// //       //which are in some shortest paths
+// //       for(typename AugGraph::EdgeIt e=res_graph.template first<typename AugGraph::EdgeIt>(); res_graph.valid(e); res_graph.next(e)) {
+// // 	if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
+// // 	  typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+// // 	  original_edge.update();
+// // 	  original_edge.set(f, e);
+// // 	  residual_capacity.update();
+// // 	  residual_capacity.set(f, res_graph.free(e));
+// // 	} 
+// //       }
+
+// //       bool __augment=true;
+
+// //       while (__augment) {
+// // 	__augment=false;
+// // 	//computing blocking flow with dfs
+// // 	typedef typename MutableGraph::NodeMap<bool> BlockingReachedMap;
+// // 	DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F);
+// // 	typename MutableGraph::NodeMap<typename MutableGraph::Edge> pred(F);
+// // 	pred.set(sF, typename MutableGraph::Edge(INVALID));
+// // 	//invalid iterators for sources
+
+// // 	typename MutableGraph::NodeMap<Number> free(F);
+
+// // 	dfs.pushAndSetReached(sF);      
+// // 	while (!dfs.finished()) {
+// // 	  ++dfs;
+// // 	  if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) {
+// // 	    if (dfs.isBNodeNewlyReached()) {
+// // 	      typename MutableGraph::Node v=F.aNode(dfs);
+// // 	      typename MutableGraph::Node w=F.bNode(dfs);
+// // 	      pred.set(w, dfs);
+// // 	      if (F.valid(pred.get(v))) {
+// // 		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
+// // 	      } else {
+// // 		free.set(w, residual_capacity.get(dfs)); 
+// // 	      }
+// // 	      if (w==tF) { 
+// // 		__augment=true; 
+// // 		_augment=true;
+// // 		break; 
+// // 	      }
+	      
+// // 	    } else {
+// // 	      F.erase(typename MutableGraph::OutEdgeIt(dfs));
+// // 	    }
+// // 	  } 
+// // 	}
+
+// // 	if (__augment) {
+// // 	  typename MutableGraph::Node n=tF;
+// // 	  Number augment_value=free.get(tF);
+// // 	  while (F.valid(pred.get(n))) { 
+// // 	    typename MutableGraph::Edge e=pred.get(n);
+// // 	    res_graph.augment(original_edge.get(e), augment_value); 
+// // 	    n=F.tail(e);
+// // 	    if (residual_capacity.get(e)==augment_value) 
+// // 	      F.erase(e); 
+// // 	    else 
+// // 	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
+// // 	  }
+// // 	}
+	
+// //       }
+            
+// //       return _augment;
+// //     }
+//     bool augmentOnBlockingFlow2() {
+//       bool _augment=false;
+
+//       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
+//       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
+//       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
+//       typedef typename EAugGraph::Edge EAugEdge;
+
+//       EAugGraph res_graph(*G, *flow, *capacity);
+
+//       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
+//       BfsIterator5< 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
+// 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
+
+
+//       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// 	if (S->get(s)) {
+// 	  Number u=0;
+// 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// 	    u+=flow->get(e);
+// 	  if (u<1) {
+// 	    bfs.pushAndSetReached(s);
+// 	    //pred.set(s, AugEdge(INVALID));
+// 	  }
+// 	}
+//       }
+
+      
+//       //bfs.pushAndSetReached(s);
+
+//       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
+// 	NodeMap<int>& dist=res_graph.dist;
+
+//       while ( !bfs.finished() ) {
+// 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
+// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+// 	}
+// 	++bfs;	
+//       } //computing distances from s in the residual graph
+
+//       bool __augment=true;
+
+//       while (__augment) {
+
+// 	__augment=false;
+// 	//computing blocking flow with dfs
+// 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
+// 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
+// 	  dfs(res_graph);
+// 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph, INVALID); 
+// 	//pred.set(s, EAugEdge(INVALID));
+// 	//invalid iterators for sources
+
+// 	typename EAugGraph::NodeMap<Number> free(res_graph);
+
+
+// 	//typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// 	if (S->get(s)) {
+// 	  Number u=0;
+// 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// 	    u+=flow->get(e);
+// 	  if (u<1) {
+// 	    dfs.pushAndSetReached(s);
+// 	    //pred.set(s, AugEdge(INVALID));
+// 	  }
+// 	}
+//       }
+
+
+
+//       //dfs.pushAndSetReached(s);
+//       typename EAugGraph::Node n;
+// 	while (!dfs.finished()) {
+// 	  ++dfs;
+// 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
+// 	    if (dfs.isBNodeNewlyReached()) {
+	  
+// 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
+// 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
+
+// 	      pred.set(w, EAugOutEdgeIt(dfs));
+// 	      if (res_graph.valid(pred.get(v))) {
+// 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
+// 	      } else {
+// 		free.set(w, res_graph.free(dfs)); 
+// 	      }
+	     
+// 	      n=w;
+// 	      if (T->get(w)) {
+// 		Number u=0;
+// 		for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
+// 		  u+=flow->get(f);
+// 		if (u<1) {
+// 		  __augment=true; 
+// 		  _augment=true;
+// 		  break; 
+// 		}
+// 	      }
+// 	    } else {
+// 	      res_graph.erase(dfs);
+// 	    }
+// 	  } 
+
+// 	}
+
+// 	if (__augment) {
+// 	  // typename EAugGraph::Node n=t;
+// 	  Number augment_value=free.get(n);
+// 	  while (res_graph.valid(pred.get(n))) { 
+// 	    EAugEdge e=pred.get(n);
+// 	    res_graph.augment(e, augment_value);
+// 	    n=res_graph.tail(e);
+// 	    if (res_graph.free(e)==0)
+// 	      res_graph.erase(e);
+// 	  }
+// 	}
+      
+//       }
+            
+//       return _augment;
+//     }
+//     void run() {
+//       //int num_of_augmentations=0;
+//       while (augmentOnShortestPath()) { 
+// 	//while (augmentOnBlockingFlow<MutableGraph>()) { 
+// 	//std::cout << ++num_of_augmentations << " ";
+// 	//std::cout<<std::endl;
+//       } 
+//     }
+// //     template<typename MutableGraph> void run() {
+// //       //int num_of_augmentations=0;
+// //       //while (augmentOnShortestPath()) { 
+// // 	while (augmentOnBlockingFlow<MutableGraph>()) { 
+// // 	//std::cout << ++num_of_augmentations << " ";
+// // 	//std::cout<<std::endl;
+// //       } 
+// //     } 
+//     Number flowValue() { 
+//       Number a=0;
+//       EdgeIt e;
+//       for(G->/*getF*/first(e); G->valid(e); G->next(e)) {
+// 	a+=flow->get(e);
+//       }
+//       return a;
+//     }
+//   };
+
+
+
+
+
+  
+// //   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+// //   class MaxFlow2 {
+// //   public:
+// //     typedef typename Graph::Node Node;
+// //     typedef typename Graph::Edge Edge;
+// //     typedef typename Graph::EdgeIt EdgeIt;
+// //     typedef typename Graph::OutEdgeIt OutEdgeIt;
+// //     typedef typename Graph::InEdgeIt InEdgeIt;
+// //   private:
+// //     const Graph& G;
+// //     std::list<Node>& S;
+// //     std::list<Node>& T;
+// //     FlowMap& flow;
+// //     const CapacityMap& capacity;
+// //     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
+// //     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
+// //     typedef typename AugGraph::Edge AugEdge;
+// //     typename Graph::NodeMap<bool> SMap;
+// //     typename Graph::NodeMap<bool> TMap;
+// //   public:
+// //     MaxFlow2(const Graph& _G, std::list<Node>& _S, std::list<Node>& _T, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { 
+// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
+// // 	  i!=S.end(); ++i) { 
+// // 	SMap.set(*i, true); 
+// //       }
+// //       for (typename std::list<Node>::const_iterator i=T.begin(); 
+// // 	   i!=T.end(); ++i) { 
+// // 	TMap.set(*i, true); 
+// //       }
+// //     }
+// //     bool augment() {
+// //       AugGraph res_graph(G, flow, capacity);
+// //       bool _augment=false;
+// //       Node reached_t_node;
+      
+// //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
+// //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
+// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
+// // 	  i!=S.end(); ++i) {
+// // 	bfs.pushAndSetReached(*i);
+// //       }
+// //       //bfs.pushAndSetReached(s);
+	
+// //       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+// //       //filled up with invalid iterators
+      
+// //       typename AugGraph::NodeMap<Number> free(res_graph);
+	
+// //       //searching for augmenting path
+// //       while ( !bfs.finished() ) { 
+// // 	AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs);
+// // 	if (e.valid() && bfs.isBNodeNewlyReached()) {
+// // 	  Node v=res_graph.tail(e);
+// // 	  Node w=res_graph.head(e);
+// // 	  pred.set(w, e);
+// // 	  if (pred.get(v).valid()) {
+// // 	    free.set(w, std::min(free.get(v), e.free()));
+// // 	  } else {
+// // 	    free.set(w, e.free()); 
+// // 	  }
+// // 	  if (TMap.get(res_graph.head(e))) { 
+// // 	    _augment=true; 
+// // 	    reached_t_node=res_graph.head(e);
+// // 	    break; 
+// // 	  }
+// // 	}
+	
+// // 	++bfs;
+// //       } //end of searching augmenting path
+
+// //       if (_augment) {
+// // 	Node n=reached_t_node;
+// // 	Number augment_value=free.get(reached_t_node);
+// // 	while (pred.get(n).valid()) { 
+// // 	  AugEdge e=pred.get(n);
+// // 	  e.augment(augment_value); 
+// // 	  n=res_graph.tail(e);
+// // 	}
+// //       }
+
+// //       return _augment;
+// //     }
+// //     void run() {
+// //       while (augment()) { } 
+// //     }
+// //     Number flowValue() { 
+// //       Number a=0;
+// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
+// // 	  i!=S.end(); ++i) { 
+// // 	for(OutEdgeIt e=G.template first<OutEdgeIt>(*i); e.valid(); ++e) {
+// // 	  a+=flow.get(e);
+// // 	}
+// // 	for(InEdgeIt e=G.template first<InEdgeIt>(*i); e.valid(); ++e) {
+// // 	  a-=flow.get(e);
+// // 	}
+// //       }
+// //       return a;
+// //     }
+// //   };
+
+
+} // namespace hugo
+
+#endif //HUGO_EDMONDS_KARP_H

Added: hugo/trunk/src/work/marci/experiment/edmonds_karp_1.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/edmonds_karp_1.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,1240 @@
+// -*- c++ -*-
+#ifndef HUGO_EDMONDS_KARP_H
+#define HUGO_EDMONDS_KARP_H
+
+#include <algorithm>
+#include <list>
+#include <iterator>
+
+#include <bfs_iterator_1.h>
+#include <invalid.h>
+#include <graph_wrapper_1.h>
+
+namespace hugo {
+
+  template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+  class ResGraph {
+  public:
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+  private:
+    typedef typename Graph::SymEdgeIt OldSymEdgeIt;
+    const Graph& G;
+    FlowMap& flow;
+    const CapacityMap& capacity;
+  public:
+    ResGraph(const Graph& _G, FlowMap& _flow, 
+	     const CapacityMap& _capacity) : 
+      G(_G), flow(_flow), capacity(_capacity) { }
+
+    class Edge; 
+    class OutEdgeIt; 
+    friend class Edge; 
+    friend class OutEdgeIt; 
+
+    class Edge {
+      friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
+    protected:
+      const ResGraph<Graph, Number, FlowMap, CapacityMap>* resG;
+      OldSymEdgeIt sym;
+    public:
+      Edge() { } 
+      //Edge(const Edge& e) : resG(e.resG), sym(e.sym) { }
+      Number free() const { 
+	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
+	  return (resG->capacity.get(sym)-resG->flow.get(sym)); 
+	} else { 
+	  return (resG->flow.get(sym)); 
+	}
+      }
+      bool valid() const { return sym.valid(); }
+      void augment(Number a) const {
+	if (resG->G.aNode(sym)==resG->G.tail(sym)) { 
+	  resG->flow.set(sym, resG->flow.get(sym)+a);
+	  //resG->flow[sym]+=a;
+	} else { 
+	  resG->flow.set(sym, resG->flow.get(sym)-a);
+	  //resG->flow[sym]-=a;
+	}
+      }
+    };
+
+    class OutEdgeIt : public Edge {
+      friend class ResGraph<Graph, Number, FlowMap, CapacityMap>;
+    public:
+      OutEdgeIt() { }
+      //OutEdgeIt(const OutEdgeIt& e) { resG=e.resG; sym=e.sym; }
+    private:
+      OutEdgeIt(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
+      	resG=&_resG;
+	sym=resG->G.template first<OldSymEdgeIt>(v);
+	while( sym.valid() && !(free()>0) ) { ++sym; }
+      }
+    public:
+      OutEdgeIt& operator++() { 
+	++sym; 
+	while( sym.valid() && !(free()>0) ) { ++sym; }
+	return *this; 
+      }
+    };
+
+    void /*getF*/first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); 
+    }
+    void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
+    
+    template< typename It >
+    It first() const { 
+      It e;      
+      /*getF*/first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      /*getF*/first(e, v);
+      return e; 
+    }
+
+    Node tail(Edge e) const { return G.aNode(e.sym); }
+    Node head(Edge e) const { return G.bNode(e.sym); }
+
+    Node aNode(OutEdgeIt e) const { return G.aNode(e.sym); }
+    Node bNode(OutEdgeIt e) const { return G.bNode(e.sym); }
+
+    int id(Node v) const { return G.id(v); }
+
+    template <typename S>
+    class NodeMap {
+      typename Graph::NodeMap<S> node_map; 
+    public:
+      NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
+      NodeMap(const ResGraph<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
+      void set(Node nit, S a) { node_map.set(nit, a); }
+      S get(Node nit) const { return node_map.get(nit); }
+      S& operator[](Node nit) { return node_map[nit]; } 
+      const S& operator[](Node nit) const { return node_map[nit]; } 
+    };
+
+  };
+
+
+  template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+  class ResGraph2 {
+  public:
+    typedef typename Graph::Node Node;
+    typedef typename Graph::NodeIt NodeIt;
+  private:
+    //typedef typename Graph::SymEdgeIt OldSymEdgeIt;
+    typedef typename Graph::OutEdgeIt OldOutEdgeIt;
+    typedef typename Graph::InEdgeIt OldInEdgeIt;
+    
+    const Graph& G;
+    FlowMap& flow;
+    const CapacityMap& capacity;
+  public:
+    ResGraph2(const Graph& _G, FlowMap& _flow, 
+	     const CapacityMap& _capacity) : 
+      G(_G), flow(_flow), capacity(_capacity) { }
+
+    class Edge; 
+    class OutEdgeIt; 
+    friend class Edge; 
+    friend class OutEdgeIt; 
+
+    class Edge {
+      friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
+    protected:
+      const ResGraph2<Graph, Number, FlowMap, CapacityMap>* resG;
+      //OldSymEdgeIt sym;
+      OldOutEdgeIt out;
+      OldInEdgeIt in;
+      bool out_or_in; //true, iff out
+    public:
+      Edge() : out_or_in(true) { } 
+      Number free() const { 
+	if (out_or_in) { 
+	  return (resG->capacity.get(out)-resG->flow.get(out)); 
+	} else { 
+	  return (resG->flow.get(in)); 
+	}
+      }
+      bool valid() const { 
+	return out_or_in && out.valid() || in.valid(); }
+      void augment(Number a) const {
+	if (out_or_in) { 
+	  resG->flow.set(out, resG->flow.get(out)+a);
+	} else { 
+	  resG->flow.set(in, resG->flow.get(in)-a);
+	}
+      }
+    };
+
+    class OutEdgeIt : public Edge {
+      friend class ResGraph2<Graph, Number, FlowMap, CapacityMap>;
+    public:
+      OutEdgeIt() { }
+    private:
+      OutEdgeIt(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _resG, Node v) { 
+      	resG=&_resG;
+	out=resG->G.template first<OldOutEdgeIt>(v);
+	while( out.valid() && !(free()>0) ) { ++out; }
+	if (!out.valid()) {
+	  out_or_in=0;
+	  in=resG->G.template first<OldInEdgeIt>(v);
+	  while( in.valid() && !(free()>0) ) { ++in; }
+	}
+      }
+    public:
+      OutEdgeIt& operator++() { 
+	if (out_or_in) {
+	  Node v=resG->G.aNode(out);
+	  ++out;
+	  while( out.valid() && !(free()>0) ) { ++out; }
+	  if (!out.valid()) {
+	    out_or_in=0;
+	    in=resG->G.template first<OldInEdgeIt>(v);
+	    while( in.valid() && !(free()>0) ) { ++in; }
+	  }
+	} else {
+	  ++in;
+	  while( in.valid() && !(free()>0) ) { ++in; } 
+	}
+	return *this; 
+      }
+    };
+
+    void /*getF*/first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); 
+    }
+    void /*getF*/first(NodeIt& v) const { G./*getF*/first(v); }
+    
+    template< typename It >
+    It first() const { 
+      It e;
+      /*getF*/first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      /*getF*/first(e, v);
+      return e; 
+    }
+
+    Node tail(Edge e) const { 
+      return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
+    Node head(Edge e) const { 
+      return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
+
+    Node aNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? G.aNode(e.out) : G.aNode(e.in)); }
+    Node bNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? G.bNode(e.out) : G.bNode(e.in)); }
+
+    int id(Node v) const { return G.id(v); }
+
+    template <typename S>
+    class NodeMap {
+      typename Graph::NodeMap<S> node_map; 
+    public:
+      NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(_G.G) { }
+      NodeMap(const ResGraph2<Graph, Number, FlowMap, CapacityMap>& _G, S a) : node_map(_G.G, a) { }
+      void set(Node nit, S a) { node_map.set(nit, a); }
+      S get(Node nit) const { return node_map.get(nit); }
+    };
+  };
+
+
+  template <typename GraphWrapper, typename Number, typename FlowMap, typename CapacityMap>
+  class MaxFlow {
+  protected:
+    typedef GraphWrapper GW;
+    typedef typename GW::Node Node;
+    typedef typename GW::Edge Edge;
+    typedef typename GW::EdgeIt EdgeIt;
+    typedef typename GW::OutEdgeIt OutEdgeIt;
+    typedef typename GW::InEdgeIt InEdgeIt;
+    //const Graph* G;
+    //GW gw;
+    const GW* g;
+    Node s;
+    Node t;
+    FlowMap* flow;
+    const CapacityMap* capacity;
+    typedef ResGraphWrapper<const GW, Number, FlowMap, CapacityMap > ResGW;
+    typedef typename ResGW::OutEdgeIt ResGWOutEdgeIt;
+    typedef typename ResGW::Edge ResGWEdge;
+  public:
+
+    MaxFlow(const GW& _g, Node _s, Node _t, FlowMap& _flow, const CapacityMap& _capacity) : 
+      g(&_g), s(_s), t(_t), flow(&_flow), capacity(&_capacity) { }
+
+    bool augmentOnShortestPath() {
+      ResGW res_graph(*g, *flow, *capacity);
+      bool _augment=false;
+      
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+      bfs.pushAndSetReached(s);
+	
+      typename ResGW::NodeMap<ResGWEdge> pred(res_graph); 
+      pred.set(s, INVALID);
+      
+      typename ResGW::NodeMap<Number> free(res_graph);
+	
+      //searching for augmenting path
+      while ( !bfs.finished() ) { 
+	ResGWOutEdgeIt e=bfs;
+	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+	  Node v=res_graph.tail(e);
+	  Node w=res_graph.head(e);
+	  pred.set(w, e);
+	  if (res_graph.valid(pred.get(v))) {
+	    free.set(w, std::min(free.get(v), res_graph.resCap(e)));
+	  } else {
+	    free.set(w, res_graph.resCap(e)); 
+	  }
+	  if (res_graph.head(e)==t) { _augment=true; break; }
+	}
+	
+	++bfs;
+      } //end of searching augmenting path
+
+      if (_augment) {
+	Node n=t;
+	Number augment_value=free.get(t);
+	while (res_graph.valid(pred.get(n))) { 
+	  ResGWEdge e=pred.get(n);
+	  res_graph.augment(e, augment_value); 
+	  n=res_graph.tail(e);
+	}
+      }
+
+      return _augment;
+    }
+
+    template<typename MapGraphWrapper> 
+    class DistanceMap {
+    protected:
+      const MapGraphWrapper* g;
+      typename MapGraphWrapper::NodeMap<int> dist; 
+    public:
+      DistanceMap(MapGraphWrapper& _g) : g(&_g), dist(*g, g->nodeNum()) { }
+      void set(const typename MapGraphWrapper::Node& n, int a) { dist[n]=a; }
+      int get(const typename MapGraphWrapper::Node& n) const { return dist[n]; }
+      bool get(const typename MapGraphWrapper::Edge& e) const { 
+	return (dist.get(g->tail(e))<dist.get(g->head(e))); 
+      }
+    };
+
+    template<typename MutableGraph> bool augmentOnBlockingFlow() {      
+      typedef MutableGraph MG;
+      bool _augment=false;
+
+      ResGW res_graph(*g, *flow, *capacity);
+
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+
+      bfs.pushAndSetReached(s);
+      //typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
+      DistanceMap<ResGW> dist(res_graph);
+      while ( !bfs.finished() ) { 
+	ResGWOutEdgeIt e=bfs;
+	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+	}
+	++bfs;
+      } //computing distances from s in the residual graph
+
+      MG F;
+      typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
+      FilterResGW filter_res_graph(res_graph, dist);
+      typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
+      {
+	typename ResGW::NodeIt n;
+	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
+	  res_graph_to_F.set(n, F.addNode());
+	}
+      }
+
+      typename MG::Node sF=res_graph_to_F.get(s);
+      typename MG::Node tF=res_graph_to_F.get(t);
+      typename MG::EdgeMap<ResGWEdge> original_edge(F);
+      typename MG::EdgeMap<Number> residual_capacity(F);
+
+      //Making F to the graph containing the edges of the residual graph 
+      //which are in some shortest paths
+      {
+	typename FilterResGW::EdgeIt e;
+	for(filter_res_graph.first(e); filter_res_graph.valid(e); filter_res_graph.next(e)) {
+	  //if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
+	  typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+	  original_edge.update();
+	  original_edge.set(f, e);
+	  residual_capacity.update();
+	  residual_capacity.set(f, res_graph.resCap(e));
+	  //} 
+	}
+      }
+
+      bool __augment=true;
+
+      while (__augment) {
+	__augment=false;
+	//computing blocking flow with dfs
+	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
+	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
+	typename MG::NodeMap<typename MG::Edge> pred(F);
+	pred.set(sF, INVALID);
+	//invalid iterators for sources
+
+	typename MG::NodeMap<Number> free(F);
+
+	dfs.pushAndSetReached(sF);      
+	while (!dfs.finished()) {
+	  ++dfs;
+	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
+	    if (dfs.isBNodeNewlyReached()) {
+	      typename MG::Node v=F.aNode(dfs);
+	      typename MG::Node w=F.bNode(dfs);
+	      pred.set(w, dfs);
+	      if (F.valid(pred.get(v))) {
+		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
+	      } else {
+		free.set(w, residual_capacity.get(dfs)); 
+	      }
+	      if (w==tF) { 
+		__augment=true; 
+		_augment=true;
+		break; 
+	      }
+	      
+	    } else {
+	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
+	    }
+	  } 
+	}
+
+	if (__augment) {
+	  typename MG::Node n=tF;
+	  Number augment_value=free.get(tF);
+	  while (F.valid(pred.get(n))) { 
+	    typename MG::Edge e=pred.get(n);
+	    res_graph.augment(original_edge.get(e), augment_value); 
+	    n=F.tail(e);
+	    if (residual_capacity.get(e)==augment_value) 
+	      F.erase(e); 
+	    else 
+	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
+	  }
+	}
+	
+      }
+            
+      return _augment;
+    }
+
+    template<typename MutableGraph> bool augmentOnBlockingFlow1() {      
+      typedef MutableGraph MG;
+      bool _augment=false;
+
+      ResGW res_graph(*g, *flow, *capacity);
+
+      //bfs for distances on the residual graph
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+      bfs.pushAndSetReached(s);
+      typename ResGW::NodeMap<int> dist(res_graph); //filled up with 0's
+
+      //F will contain the physical copy of the residual graph
+      //with the set of edges which are on shortest paths
+      MG F;
+      typename ResGW::NodeMap<typename MG::Node> res_graph_to_F(res_graph);
+      {
+	typename ResGW::NodeIt n;
+	for(res_graph.first(n); res_graph.valid(n); res_graph.next(n)) {
+	  res_graph_to_F.set(n, F.addNode());
+	}
+      }
+
+      typename MG::Node sF=res_graph_to_F.get(s);
+      typename MG::Node tF=res_graph_to_F.get(t);
+      typename MG::EdgeMap<ResGWEdge> original_edge(F);
+      typename MG::EdgeMap<Number> residual_capacity(F);
+
+      while ( !bfs.finished() ) { 
+	ResGWOutEdgeIt e=bfs;
+	if (res_graph.valid(e)) {
+	  if (bfs.isBNodeNewlyReached()) {
+	    dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+	    typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+	    original_edge.update();
+	    original_edge.set(f, e);
+	    residual_capacity.update();
+	    residual_capacity.set(f, res_graph.resCap(e));
+	  } else {
+	    if (dist.get(res_graph.head(e))==(dist.get(res_graph.tail(e))+1)) {
+	      typename MG::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+	      original_edge.update();
+	      original_edge.set(f, e);
+	      residual_capacity.update();
+	      residual_capacity.set(f, res_graph.resCap(e));
+	    }
+	  }
+	}
+	++bfs;
+      } //computing distances from s in the residual graph
+
+      bool __augment=true;
+
+      while (__augment) {
+	__augment=false;
+	//computing blocking flow with dfs
+	typedef typename TrivGraphWrapper<MG>::NodeMap<bool> BlockingReachedMap;
+	DfsIterator5< TrivGraphWrapper<MG>, BlockingReachedMap > dfs(F);
+	typename MG::NodeMap<typename MG::Edge> pred(F);
+	pred.set(sF, INVALID);
+	//invalid iterators for sources
+
+	typename MG::NodeMap<Number> free(F);
+
+	dfs.pushAndSetReached(sF);      
+	while (!dfs.finished()) {
+	  ++dfs;
+	  if (F.valid(/*typename MG::OutEdgeIt*/(dfs))) {
+	    if (dfs.isBNodeNewlyReached()) {
+	      typename MG::Node v=F.aNode(dfs);
+	      typename MG::Node w=F.bNode(dfs);
+	      pred.set(w, dfs);
+	      if (F.valid(pred.get(v))) {
+		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
+	      } else {
+		free.set(w, residual_capacity.get(dfs)); 
+	      }
+	      if (w==tF) { 
+		__augment=true; 
+		_augment=true;
+		break; 
+	      }
+	      
+	    } else {
+	      F.erase(/*typename MG::OutEdgeIt*/(dfs));
+	    }
+	  } 
+	}
+
+	if (__augment) {
+	  typename MG::Node n=tF;
+	  Number augment_value=free.get(tF);
+	  while (F.valid(pred.get(n))) { 
+	    typename MG::Edge e=pred.get(n);
+	    res_graph.augment(original_edge.get(e), augment_value); 
+	    n=F.tail(e);
+	    if (residual_capacity.get(e)==augment_value) 
+	      F.erase(e); 
+	    else 
+	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
+	  }
+	}
+	
+      }
+            
+      return _augment;
+    }
+
+    bool augmentOnBlockingFlow2() {
+      bool _augment=false;
+
+      ResGW res_graph(*g, *flow, *capacity);
+
+      typedef typename ResGW::NodeMap<bool> ReachedMap;
+      BfsIterator5< ResGW, ReachedMap > bfs(res_graph);
+
+      bfs.pushAndSetReached(s);
+      DistanceMap<ResGW> dist(res_graph);
+      while ( !bfs.finished() ) { 
+ 	ResGWOutEdgeIt e=bfs;
+ 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+ 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+ 	}
+	++bfs;
+      } //computing distances from s in the residual graph
+
+      //Subgraph containing the edges on some shortest paths
+      typedef SubGraphWrapper<ResGW, DistanceMap<ResGW> > FilterResGW;
+      FilterResGW filter_res_graph(res_graph, dist);
+
+      //Subgraph, which is able to delete edges which are already 
+      //met by the dfs
+      typename FilterResGW::NodeMap<typename FilterResGW::OutEdgeIt> 
+ 	first_out_edges(filter_res_graph);
+      typename FilterResGW::NodeIt v;
+      for(filter_res_graph.first(v); filter_res_graph.valid(v); 
+ 	  filter_res_graph.next(v)) 
+      {
+ 	typename FilterResGW::OutEdgeIt e;
+ 	filter_res_graph.first(e, v);
+ 	first_out_edges.set(v, e);
+      }
+      typedef ErasingFirstGraphWrapper<FilterResGW, typename FilterResGW::
+	NodeMap<typename FilterResGW::OutEdgeIt> > ErasingResGW;
+      ErasingResGW erasing_res_graph(filter_res_graph, first_out_edges);
+
+      bool __augment=true;
+
+      while (__augment) {
+
+ 	__augment=false;
+ 	//computing blocking flow with dfs
+	typedef typename ErasingResGW::NodeMap<bool> BlockingReachedMap;
+ 	DfsIterator5< ErasingResGW, BlockingReachedMap > 
+ 	  dfs(erasing_res_graph);
+ 	typename ErasingResGW::NodeMap<typename ErasingResGW::OutEdgeIt> 
+ 	  pred(erasing_res_graph); 
+ 	pred.set(s, INVALID);
+ 	//invalid iterators for sources
+
+ 	typename ErasingResGW::NodeMap<Number> free(erasing_res_graph);
+
+ 	dfs.pushAndSetReached(s);
+ 	while (!dfs.finished()) {
+ 	  ++dfs;
+ 	  if (erasing_res_graph.valid(
+ 		/*typename ErasingResGW::OutEdgeIt*/(dfs))) 
+ 	  { 
+ 	    if (dfs.isBNodeNewlyReached()) {
+	  
+ 	      typename ErasingResGW::Node v=erasing_res_graph.aNode(dfs);
+ 	      typename ErasingResGW::Node w=erasing_res_graph.bNode(dfs);
+
+ 	      pred.set(w, /*typename ErasingResGW::OutEdgeIt*/(dfs));
+ 	      if (erasing_res_graph.valid(pred.get(v))) {
+ 		free.set(w, std::min(free.get(v), res_graph.resCap(dfs)));
+ 	      } else {
+ 		free.set(w, res_graph.resCap(dfs)); 
+ 	      }
+	      
+ 	      if (w==t) { 
+ 		__augment=true; 
+ 		_augment=true;
+ 		break; 
+ 	      }
+	    } else {
+	      erasing_res_graph.erase(dfs);
+	    }
+	  }
+	}	
+
+ 	if (__augment) {
+ 	  typename ErasingResGW::Node n=t;
+ 	  Number augment_value=free.get(n);
+ 	  while (erasing_res_graph.valid(pred.get(n))) { 
+ 	    typename ErasingResGW::OutEdgeIt e=pred.get(n);
+ 	    res_graph.augment(e, augment_value);
+ 	    n=erasing_res_graph.tail(e);
+ 	    if (res_graph.resCap(e)==0)
+ 	      erasing_res_graph.erase(e);
+ 	  }
+ 	}
+      
+      } //while (__augment) 
+            
+      return _augment;
+    }
+
+//     bool augmentOnBlockingFlow2() {
+//       bool _augment=false;
+
+//       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
+//       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
+//       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
+//       typedef typename EAugGraph::Edge EAugEdge;
+
+//       EAugGraph res_graph(*G, *flow, *capacity);
+
+//       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
+//       BfsIterator5< 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
+// 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
+      
+//       bfs.pushAndSetReached(s);
+
+//       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
+// 	NodeMap<int>& dist=res_graph.dist;
+
+//       while ( !bfs.finished() ) {
+// 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
+// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+// 	}
+// 	++bfs;	
+//       } //computing distances from s in the residual graph
+
+//       bool __augment=true;
+
+//       while (__augment) {
+
+// 	__augment=false;
+// 	//computing blocking flow with dfs
+// 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
+// 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
+// 	  dfs(res_graph);
+// 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph); 
+// 	pred.set(s, EAugEdge(INVALID));
+// 	//invalid iterators for sources
+
+// 	typename EAugGraph::NodeMap<Number> free(res_graph);
+
+// 	dfs.pushAndSetReached(s);
+// 	while (!dfs.finished()) {
+// 	  ++dfs;
+// 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
+// 	    if (dfs.isBNodeNewlyReached()) {
+	  
+// 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
+// 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
+
+// 	      pred.set(w, EAugOutEdgeIt(dfs));
+// 	      if (res_graph.valid(pred.get(v))) {
+// 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
+// 	      } else {
+// 		free.set(w, res_graph.free(dfs)); 
+// 	      }
+	      
+// 	      if (w==t) { 
+// 		__augment=true; 
+// 		_augment=true;
+// 		break; 
+// 	      }
+// 	    } else {
+// 	      res_graph.erase(dfs);
+// 	    }
+// 	  } 
+
+// 	}
+
+// 	if (__augment) {
+// 	  typename EAugGraph::Node n=t;
+// 	  Number augment_value=free.get(t);
+// 	  while (res_graph.valid(pred.get(n))) { 
+// 	    EAugEdge e=pred.get(n);
+// 	    res_graph.augment(e, augment_value);
+// 	    n=res_graph.tail(e);
+// 	    if (res_graph.free(e)==0)
+// 	      res_graph.erase(e);
+// 	  }
+// 	}
+      
+//       }
+            
+//       return _augment;
+//     }
+
+    void run() {
+      //int num_of_augmentations=0;
+      while (augmentOnShortestPath()) { 
+	//while (augmentOnBlockingFlow<MutableGraph>()) { 
+	//std::cout << ++num_of_augmentations << " ";
+	//std::cout<<std::endl;
+      } 
+    }
+
+    template<typename MutableGraph> void run() {
+      //int num_of_augmentations=0;
+      //while (augmentOnShortestPath()) { 
+	while (augmentOnBlockingFlow<MutableGraph>()) { 
+	//std::cout << ++num_of_augmentations << " ";
+	//std::cout<<std::endl;
+      } 
+    }
+
+    Number flowValue() { 
+      Number a=0;
+      OutEdgeIt e;
+      for(g->first(e, s); g->valid(e); g->next(e)) {
+	a+=flow->get(e);
+      }
+      return a;
+    }
+
+  };
+
+
+//   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+//   class MaxMatching {
+//   public:
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::NodeIt NodeIt;
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::EdgeIt EdgeIt;
+//     typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     typedef typename Graph::InEdgeIt InEdgeIt;
+
+//     typedef typename Graph::NodeMap<bool> SMap;
+//     typedef typename Graph::NodeMap<bool> TMap;
+//   private:
+//     const Graph* G;
+//     SMap* S;
+//     TMap* T;
+//     //Node s;
+//     //Node t;
+//     FlowMap* flow;
+//     const CapacityMap* capacity;
+//     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
+//     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
+//     typedef typename AugGraph::Edge AugEdge;
+//     typename Graph::NodeMap<int> used; //0
+
+//   public:
+//     MaxMatching(const Graph& _G, SMap& _S, TMap& _T, FlowMap& _flow, const CapacityMap& _capacity) : 
+//       G(&_G), S(&_S), T(&_T), flow(&_flow), capacity(&_capacity), used(_G) { }
+//     bool augmentOnShortestPath() {
+//       AugGraph res_graph(*G, *flow, *capacity);
+//       bool _augment=false;
+      
+//       typedef typename AugGraph::NodeMap<bool> ReachedMap;
+//       BfsIterator5< AugGraph, /*AugOutEdgeIt,*/ ReachedMap > bfs(res_graph);
+//       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// 	if ((S->get(s)) && (used.get(s)<1) ) {
+// 	  //Number u=0;
+// 	  //for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// 	  //u+=flow->get(e);
+// 	  //if (u<1) {
+// 	    bfs.pushAndSetReached(s);
+// 	    pred.set(s, AugEdge(INVALID));
+// 	    //}
+// 	}
+//       }
+      
+//       typename AugGraph::NodeMap<Number> free(res_graph);
+	
+//       Node n;
+//       //searching for augmenting path
+//       while ( !bfs.finished() ) { 
+// 	AugOutEdgeIt e=bfs;
+// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// 	  Node v=res_graph.tail(e);
+// 	  Node w=res_graph.head(e);
+// 	  pred.set(w, e);
+// 	  if (res_graph.valid(pred.get(v))) {
+// 	    free.set(w, std::min(free.get(v), res_graph.free(e)));
+// 	  } else {
+// 	    free.set(w, res_graph.free(e)); 
+// 	  }
+// 	  n=res_graph.head(e);
+// 	  if (T->get(n) && (used.get(n)<1) ) { 
+// 	    //Number u=0;
+// 	    //for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
+// 	    //u+=flow->get(f);
+// 	    //if (u<1) {
+// 	      _augment=true; 
+// 	      break; 
+// 	      //}
+// 	  }
+// 	}
+	
+// 	++bfs;
+//       } //end of searching augmenting path
+
+//       if (_augment) {
+// 	//Node n=t;
+// 	used.set(n, 1); //mind2 vegen jav
+// 	Number augment_value=free.get(n);
+// 	while (res_graph.valid(pred.get(n))) { 
+// 	  AugEdge e=pred.get(n);
+// 	  res_graph.augment(e, augment_value); 
+// 	  n=res_graph.tail(e);
+// 	}
+// 	used.set(n, 1); //mind2 vegen jav
+//       }
+
+//       return _augment;
+//     }
+
+// //     template<typename MutableGraph> bool augmentOnBlockingFlow() {      
+// //       bool _augment=false;
+
+// //       AugGraph res_graph(*G, *flow, *capacity);
+
+// //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
+// //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
+
+
+
+
+
+// //       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+// //       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// // 	if (S->get(s)) {
+// // 	  Number u=0;
+// // 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// // 	    u+=flow->get(e);
+// // 	  if (u<1) {
+// // 	    bfs.pushAndSetReached(s);
+// // 	    //pred.set(s, AugEdge(INVALID));
+// // 	  }
+// // 	}
+// //       }
+
+
+
+
+// //       //bfs.pushAndSetReached(s);
+// //       typename AugGraph::NodeMap<int> dist(res_graph); //filled up with 0's
+// //       while ( !bfs.finished() ) { 
+// // 	AugOutEdgeIt e=bfs;
+// // 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// // 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+// // 	}
+	
+// // 	++bfs;
+// //       } //computing distances from s in the residual graph
+
+// //       MutableGraph F;
+// //       typename AugGraph::NodeMap<typename MutableGraph::Node> 
+// // 	res_graph_to_F(res_graph);
+// //       for(typename AugGraph::NodeIt n=res_graph.template first<typename AugGraph::NodeIt>(); res_graph.valid(n); res_graph.next(n)) {
+// // 	res_graph_to_F.set(n, F.addNode());
+// //       }
+      
+// //       typename MutableGraph::Node sF=res_graph_to_F.get(s);
+// //       typename MutableGraph::Node tF=res_graph_to_F.get(t);
+
+// //       typename MutableGraph::EdgeMap<AugEdge> original_edge(F);
+// //       typename MutableGraph::EdgeMap<Number> residual_capacity(F);
+
+// //       //Making F to the graph containing the edges of the residual graph 
+// //       //which are in some shortest paths
+// //       for(typename AugGraph::EdgeIt e=res_graph.template first<typename AugGraph::EdgeIt>(); res_graph.valid(e); res_graph.next(e)) {
+// // 	if (dist.get(res_graph.head(e))==dist.get(res_graph.tail(e))+1) {
+// // 	  typename MutableGraph::Edge f=F.addEdge(res_graph_to_F.get(res_graph.tail(e)), res_graph_to_F.get(res_graph.head(e)));
+// // 	  original_edge.update();
+// // 	  original_edge.set(f, e);
+// // 	  residual_capacity.update();
+// // 	  residual_capacity.set(f, res_graph.free(e));
+// // 	} 
+// //       }
+
+// //       bool __augment=true;
+
+// //       while (__augment) {
+// // 	__augment=false;
+// // 	//computing blocking flow with dfs
+// // 	typedef typename MutableGraph::NodeMap<bool> BlockingReachedMap;
+// // 	DfsIterator4< MutableGraph, typename MutableGraph::OutEdgeIt, BlockingReachedMap > dfs(F);
+// // 	typename MutableGraph::NodeMap<typename MutableGraph::Edge> pred(F);
+// // 	pred.set(sF, typename MutableGraph::Edge(INVALID));
+// // 	//invalid iterators for sources
+
+// // 	typename MutableGraph::NodeMap<Number> free(F);
+
+// // 	dfs.pushAndSetReached(sF);      
+// // 	while (!dfs.finished()) {
+// // 	  ++dfs;
+// // 	  if (F.valid(typename MutableGraph::OutEdgeIt(dfs))) {
+// // 	    if (dfs.isBNodeNewlyReached()) {
+// // 	      typename MutableGraph::Node v=F.aNode(dfs);
+// // 	      typename MutableGraph::Node w=F.bNode(dfs);
+// // 	      pred.set(w, dfs);
+// // 	      if (F.valid(pred.get(v))) {
+// // 		free.set(w, std::min(free.get(v), residual_capacity.get(dfs)));
+// // 	      } else {
+// // 		free.set(w, residual_capacity.get(dfs)); 
+// // 	      }
+// // 	      if (w==tF) { 
+// // 		__augment=true; 
+// // 		_augment=true;
+// // 		break; 
+// // 	      }
+	      
+// // 	    } else {
+// // 	      F.erase(typename MutableGraph::OutEdgeIt(dfs));
+// // 	    }
+// // 	  } 
+// // 	}
+
+// // 	if (__augment) {
+// // 	  typename MutableGraph::Node n=tF;
+// // 	  Number augment_value=free.get(tF);
+// // 	  while (F.valid(pred.get(n))) { 
+// // 	    typename MutableGraph::Edge e=pred.get(n);
+// // 	    res_graph.augment(original_edge.get(e), augment_value); 
+// // 	    n=F.tail(e);
+// // 	    if (residual_capacity.get(e)==augment_value) 
+// // 	      F.erase(e); 
+// // 	    else 
+// // 	      residual_capacity.set(e, residual_capacity.get(e)-augment_value);
+// // 	  }
+// // 	}
+	
+// //       }
+            
+// //       return _augment;
+// //     }
+//     bool augmentOnBlockingFlow2() {
+//       bool _augment=false;
+
+//       //typedef ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> EAugGraph;
+//       typedef FilterGraphWrapper< ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > EAugGraph;
+//       typedef typename EAugGraph::OutEdgeIt EAugOutEdgeIt;
+//       typedef typename EAugGraph::Edge EAugEdge;
+
+//       EAugGraph res_graph(*G, *flow, *capacity);
+
+//       //typedef typename EAugGraph::NodeMap<bool> ReachedMap;
+//       BfsIterator5< 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>, 
+// 	/*typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt,*/ 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<bool> > bfs(res_graph);
+
+
+//       //typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// 	if (S->get(s)) {
+// 	  Number u=0;
+// 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// 	    u+=flow->get(e);
+// 	  if (u<1) {
+// 	    bfs.pushAndSetReached(s);
+// 	    //pred.set(s, AugEdge(INVALID));
+// 	  }
+// 	}
+//       }
+
+      
+//       //bfs.pushAndSetReached(s);
+
+//       typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::
+// 	NodeMap<int>& dist=res_graph.dist;
+
+//       while ( !bfs.finished() ) {
+// 	typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt e=bfs;
+// 	if (res_graph.valid(e) && bfs.isBNodeNewlyReached()) {
+// 	  dist.set(res_graph.head(e), dist.get(res_graph.tail(e))+1);
+// 	}
+// 	++bfs;	
+//       } //computing distances from s in the residual graph
+
+//       bool __augment=true;
+
+//       while (__augment) {
+
+// 	__augment=false;
+// 	//computing blocking flow with dfs
+// 	typedef typename EAugGraph::NodeMap<bool> BlockingReachedMap;
+// 	DfsIterator5< EAugGraph/*, EAugOutEdgeIt*/, BlockingReachedMap > 
+// 	  dfs(res_graph);
+// 	typename EAugGraph::NodeMap<EAugEdge> pred(res_graph, INVALID); 
+// 	//pred.set(s, EAugEdge(INVALID));
+// 	//invalid iterators for sources
+
+// 	typename EAugGraph::NodeMap<Number> free(res_graph);
+
+
+// 	//typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+//       for(NodeIt s=G->template first<NodeIt>(); G->valid(s); G->next(s)) {
+// 	if (S->get(s)) {
+// 	  Number u=0;
+// 	  for(OutEdgeIt e=G->template first<OutEdgeIt>(s); G->valid(e); G->next(e))
+// 	    u+=flow->get(e);
+// 	  if (u<1) {
+// 	    dfs.pushAndSetReached(s);
+// 	    //pred.set(s, AugEdge(INVALID));
+// 	  }
+// 	}
+//       }
+
+
+
+//       //dfs.pushAndSetReached(s);
+//       typename EAugGraph::Node n;
+// 	while (!dfs.finished()) {
+// 	  ++dfs;
+// 	  if (res_graph.valid(EAugOutEdgeIt(dfs))) { 
+// 	    if (dfs.isBNodeNewlyReached()) {
+	  
+// 	      typename EAugGraph::Node v=res_graph.aNode(dfs);
+// 	      typename EAugGraph::Node w=res_graph.bNode(dfs);
+
+// 	      pred.set(w, EAugOutEdgeIt(dfs));
+// 	      if (res_graph.valid(pred.get(v))) {
+// 		free.set(w, std::min(free.get(v), res_graph.free(dfs)));
+// 	      } else {
+// 		free.set(w, res_graph.free(dfs)); 
+// 	      }
+	     
+// 	      n=w;
+// 	      if (T->get(w)) {
+// 		Number u=0;
+// 		for(InEdgeIt f=G->template first<InEdgeIt>(n); G->valid(f); G->next(f))
+// 		  u+=flow->get(f);
+// 		if (u<1) {
+// 		  __augment=true; 
+// 		  _augment=true;
+// 		  break; 
+// 		}
+// 	      }
+// 	    } else {
+// 	      res_graph.erase(dfs);
+// 	    }
+// 	  } 
+
+// 	}
+
+// 	if (__augment) {
+// 	  // typename EAugGraph::Node n=t;
+// 	  Number augment_value=free.get(n);
+// 	  while (res_graph.valid(pred.get(n))) { 
+// 	    EAugEdge e=pred.get(n);
+// 	    res_graph.augment(e, augment_value);
+// 	    n=res_graph.tail(e);
+// 	    if (res_graph.free(e)==0)
+// 	      res_graph.erase(e);
+// 	  }
+// 	}
+      
+//       }
+            
+//       return _augment;
+//     }
+//     void run() {
+//       //int num_of_augmentations=0;
+//       while (augmentOnShortestPath()) { 
+// 	//while (augmentOnBlockingFlow<MutableGraph>()) { 
+// 	//std::cout << ++num_of_augmentations << " ";
+// 	//std::cout<<std::endl;
+//       } 
+//     }
+// //     template<typename MutableGraph> void run() {
+// //       //int num_of_augmentations=0;
+// //       //while (augmentOnShortestPath()) { 
+// // 	while (augmentOnBlockingFlow<MutableGraph>()) { 
+// // 	//std::cout << ++num_of_augmentations << " ";
+// // 	//std::cout<<std::endl;
+// //       } 
+// //     } 
+//     Number flowValue() { 
+//       Number a=0;
+//       EdgeIt e;
+//       for(G->/*getF*/first(e); G->valid(e); G->next(e)) {
+// 	a+=flow->get(e);
+//       }
+//       return a;
+//     }
+//   };
+
+
+
+
+
+  
+// //   template <typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+// //   class MaxFlow2 {
+// //   public:
+// //     typedef typename Graph::Node Node;
+// //     typedef typename Graph::Edge Edge;
+// //     typedef typename Graph::EdgeIt EdgeIt;
+// //     typedef typename Graph::OutEdgeIt OutEdgeIt;
+// //     typedef typename Graph::InEdgeIt InEdgeIt;
+// //   private:
+// //     const Graph& G;
+// //     std::list<Node>& S;
+// //     std::list<Node>& T;
+// //     FlowMap& flow;
+// //     const CapacityMap& capacity;
+// //     typedef ResGraphWrapper<Graph, Number, FlowMap, CapacityMap > AugGraph;
+// //     typedef typename AugGraph::OutEdgeIt AugOutEdgeIt;
+// //     typedef typename AugGraph::Edge AugEdge;
+// //     typename Graph::NodeMap<bool> SMap;
+// //     typename Graph::NodeMap<bool> TMap;
+// //   public:
+// //     MaxFlow2(const Graph& _G, std::list<Node>& _S, std::list<Node>& _T, FlowMap& _flow, const CapacityMap& _capacity) : G(_G), S(_S), T(_T), flow(_flow), capacity(_capacity), SMap(_G), TMap(_G) { 
+// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
+// // 	  i!=S.end(); ++i) { 
+// // 	SMap.set(*i, true); 
+// //       }
+// //       for (typename std::list<Node>::const_iterator i=T.begin(); 
+// // 	   i!=T.end(); ++i) { 
+// // 	TMap.set(*i, true); 
+// //       }
+// //     }
+// //     bool augment() {
+// //       AugGraph res_graph(G, flow, capacity);
+// //       bool _augment=false;
+// //       Node reached_t_node;
+      
+// //       typedef typename AugGraph::NodeMap<bool> ReachedMap;
+// //       BfsIterator4< AugGraph, AugOutEdgeIt, ReachedMap > bfs(res_graph);
+// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
+// // 	  i!=S.end(); ++i) {
+// // 	bfs.pushAndSetReached(*i);
+// //       }
+// //       //bfs.pushAndSetReached(s);
+	
+// //       typename AugGraph::NodeMap<AugEdge> pred(res_graph); 
+// //       //filled up with invalid iterators
+      
+// //       typename AugGraph::NodeMap<Number> free(res_graph);
+	
+// //       //searching for augmenting path
+// //       while ( !bfs.finished() ) { 
+// // 	AugOutEdgeIt e=/*AugOutEdgeIt*/(bfs);
+// // 	if (e.valid() && bfs.isBNodeNewlyReached()) {
+// // 	  Node v=res_graph.tail(e);
+// // 	  Node w=res_graph.head(e);
+// // 	  pred.set(w, e);
+// // 	  if (pred.get(v).valid()) {
+// // 	    free.set(w, std::min(free.get(v), e.free()));
+// // 	  } else {
+// // 	    free.set(w, e.free()); 
+// // 	  }
+// // 	  if (TMap.get(res_graph.head(e))) { 
+// // 	    _augment=true; 
+// // 	    reached_t_node=res_graph.head(e);
+// // 	    break; 
+// // 	  }
+// // 	}
+	
+// // 	++bfs;
+// //       } //end of searching augmenting path
+
+// //       if (_augment) {
+// // 	Node n=reached_t_node;
+// // 	Number augment_value=free.get(reached_t_node);
+// // 	while (pred.get(n).valid()) { 
+// // 	  AugEdge e=pred.get(n);
+// // 	  e.augment(augment_value); 
+// // 	  n=res_graph.tail(e);
+// // 	}
+// //       }
+
+// //       return _augment;
+// //     }
+// //     void run() {
+// //       while (augment()) { } 
+// //     }
+// //     Number flowValue() { 
+// //       Number a=0;
+// //       for(typename std::list<Node>::const_iterator i=S.begin(); 
+// // 	  i!=S.end(); ++i) { 
+// // 	for(OutEdgeIt e=G.template first<OutEdgeIt>(*i); e.valid(); ++e) {
+// // 	  a+=flow.get(e);
+// // 	}
+// // 	for(InEdgeIt e=G.template first<InEdgeIt>(*i); e.valid(); ++e) {
+// // 	  a-=flow.get(e);
+// // 	}
+// //       }
+// //       return a;
+// //     }
+// //   };
+
+
+} // namespace hugo
+
+#endif //HUGO_EDMONDS_KARP_H

Added: hugo/trunk/src/work/marci/experiment/edmonds_karp_demo.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/edmonds_karp_demo.cc	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,218 @@
+// -*- c++ -*-
+#include <iostream>
+#include <fstream>
+
+#include <list_graph.h>
+#include <smart_graph.h>
+#include <dimacs.h>
+#include <edmonds_karp.h>
+#include <time_measure.h>
+#include <graph_wrapper.h>
+
+class CM {
+public:
+  template<typename T> int get(T) const {return 1;}
+};
+
+using namespace hugo;
+
+// Use a DIMACS max flow file as stdin.
+// read_dimacs_demo < dimacs_max_flow_file
+
+
+//   struct Ize {
+//   };
+  
+//   struct Mize {
+//     Ize bumm;
+//   };
+
+//   template <typename B>
+//     class Huha {
+//     public:
+//       int u;
+//       B brr;
+//     };
+
+
+int main(int, char **) {
+
+  typedef ListGraph MutableGraph;
+
+  //typedef SmartGraph Graph;
+  typedef ListGraph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::EdgeIt EdgeIt;
+
+
+//   Mize mize[10];
+//   Mize bize[0];
+//   Mize zize;
+//   typedef Mize Tize[0];
+
+//   std::cout << &zize << " " << sizeof(mize) << sizeof(Tize) << std::endl;
+//   std::cout << sizeof(bize) << std::endl;
+
+
+//   Huha<Tize> k;
+//   std::cout << sizeof(k) << std::endl;
+
+
+//   struct Bumm {
+//     //int a;
+//     bool b;
+//   };
+
+//   std::cout << sizeof(Bumm) << std::endl;
+
+
+  Graph G;
+  Node s, t;
+  Graph::EdgeMap<int> cap(G);
+  readDimacsMaxFlow(std::cin, G, s, t, cap);
+
+//   typedef TrivGraphWrapper<Graph> TGW;
+//   TGW gw(G);
+//   TGW::NodeIt sw;
+//   gw./*getF*/first(sw);
+//   std::cout << "p1:" << gw.nodeNum() << std::endl;
+//   gw.erase(sw);
+//   std::cout << "p2:" << gw.nodeNum() << std::endl;
+
+//   typedef const Graph cLG;
+//   typedef TrivGraphWrapper<const cLG> CTGW;
+//   CTGW cgw(G);
+//   CTGW::NodeIt csw;
+//   cgw./*getF*/first(csw);
+//   std::cout << "p1:" << cgw.nodeNum() << std::endl;
+//   //cgw.erase(csw);
+//   std::cout << "p2:" << cgw.nodeNum() << std::endl;
+
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (physical blocking flow augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW > max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnBlockingFlow<MutableGraph>()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (physical blocking flow 1 augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW > max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (on-the-fly blocking flow augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW > max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnBlockingFlow2()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (on-the-fly shortest path augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW> max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnShortestPath()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+
+  return 0;
+}

Added: hugo/trunk/src/work/marci/experiment/edmonds_karp_demo_1.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/edmonds_karp_demo_1.cc	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,218 @@
+// -*- c++ -*-
+#include <iostream>
+#include <fstream>
+
+#include <list_graph.h>
+//#include <smart_graph.h>
+#include <dimacs.h>
+#include <edmonds_karp_1.h>
+#include <time_measure.h>
+#include <graph_wrapper_1.h>
+
+class CM {
+public:
+  template<typename T> int get(T) const {return 1;}
+};
+
+using namespace hugo;
+
+// Use a DIMACS max flow file as stdin.
+// read_dimacs_demo < dimacs_max_flow_file
+
+
+//   struct Ize {
+//   };
+  
+//   struct Mize {
+//     Ize bumm;
+//   };
+
+//   template <typename B>
+//     class Huha {
+//     public:
+//       int u;
+//       B brr;
+//     };
+
+
+int main(int, char **) {
+
+  typedef ListGraph MutableGraph;
+
+  //typedef SmartGraph Graph;
+  typedef ListGraph Graph;
+  typedef Graph::Node Node;
+  typedef Graph::EdgeIt EdgeIt;
+
+
+//   Mize mize[10];
+//   Mize bize[0];
+//   Mize zize;
+//   typedef Mize Tize[0];
+
+//   std::cout << &zize << " " << sizeof(mize) << sizeof(Tize) << std::endl;
+//   std::cout << sizeof(bize) << std::endl;
+
+
+//   Huha<Tize> k;
+//   std::cout << sizeof(k) << std::endl;
+
+
+//   struct Bumm {
+//     //int a;
+//     bool b;
+//   };
+
+//   std::cout << sizeof(Bumm) << std::endl;
+
+
+  Graph G;
+  Node s, t;
+  Graph::EdgeMap<int> cap(G);
+  readDimacsMaxFlow(std::cin, G, s, t, cap);
+
+//   typedef TrivGraphWrapper<Graph> TGW;
+//   TGW gw(G);
+//   TGW::NodeIt sw;
+//   gw./*getF*/first(sw);
+//   std::cout << "p1:" << gw.nodeNum() << std::endl;
+//   gw.erase(sw);
+//   std::cout << "p2:" << gw.nodeNum() << std::endl;
+
+//   typedef const Graph cLG;
+//   typedef TrivGraphWrapper<const cLG> CTGW;
+//   CTGW cgw(G);
+//   CTGW::NodeIt csw;
+//   cgw./*getF*/first(csw);
+//   std::cout << "p1:" << cgw.nodeNum() << std::endl;
+//   //cgw.erase(csw);
+//   std::cout << "p2:" << cgw.nodeNum() << std::endl;
+
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (physical blocking flow augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW > max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnBlockingFlow<MutableGraph>()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (physical blocking flow 1 augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW > max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnBlockingFlow1<MutableGraph>()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (on-the-fly blocking flow augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW > max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnBlockingFlow2()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+    std::cout << "edmonds karp demo (on-the-fly shortest path augmentation)..." << std::endl;
+    GW::EdgeMap<int> flow(gw); //0 flow
+
+    Timer ts;
+    ts.reset();
+
+    typedef GW::EdgeMapWrapper< Graph::EdgeMap<int>, int > EMW;
+    EMW cw(cap);
+    MaxFlow<GW, int, GW::EdgeMap<int>, EMW> max_flow_test(gw, s, t, flow, cw);
+    int i=0;
+    while (max_flow_test.augmentOnShortestPath()) { 
+//     for(EdgeIt e=G.template first<EdgeIt>(); e.valid(); ++e) { 
+//       std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//     }
+//     std::cout<<std::endl;
+      ++i; 
+    }
+
+//   std::cout << "maximum flow: "<< std::endl;
+//   for(EdgeIt e=G.first<EdgeIt>(); e.valid(); ++e) { 
+//     std::cout<<"("<<G.tail(e)<< "-"<<flow.get(e)<<"->"<<G.head(e)<<") ";
+//   }
+//   std::cout<<std::endl;
+    std::cout << "elapsed time: " << ts << std::endl;
+    std::cout << "number of augmentation phases: " << i << std::endl; 
+    std::cout << "flow value: "<< max_flow_test.flowValue() << std::endl;
+  }
+
+
+  return 0;
+}

Added: hugo/trunk/src/work/marci/experiment/graph_wrapper.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/graph_wrapper.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,1707 @@
+// -*- c++ -*-
+#ifndef HUGO_GRAPH_WRAPPER_H
+#define HUGO_GRAPH_WRAPPER_H
+
+#include <invalid.h>
+
+namespace hugo {
+
+  template<typename Graph>
+  class TrivGraphWrapper {
+  protected:
+    Graph* graph;
+  
+  public:
+    typedef Graph BaseGraph;
+
+    typedef typename Graph::Node Node;
+    class NodeIt : public Graph::NodeIt { 
+    public:
+      NodeIt() { }
+      NodeIt(const typename Graph::NodeIt& n) : Graph::NodeIt(n) { }
+      NodeIt(const Invalid& i) : Graph::NodeIt(i) { }
+      NodeIt(const TrivGraphWrapper<Graph>& _G) : 
+	Graph::NodeIt(*(_G.graph)) { }
+    };
+    typedef typename Graph::Edge Edge;
+    //typedef typename Graph::OutEdgeIt OutEdgeIt;
+    class OutEdgeIt : public Graph::OutEdgeIt { 
+    public:
+      OutEdgeIt() { }
+      OutEdgeIt(const typename Graph::OutEdgeIt& e) : Graph::OutEdgeIt(e) { }
+      OutEdgeIt(const Invalid& i) : Graph::OutEdgeIt(i) { }
+      OutEdgeIt(const TrivGraphWrapper<Graph>& _G, const Node& n) : 
+	Graph::OutEdgeIt(*(_G.graph), n) { }
+    };
+    //typedef typename Graph::InEdgeIt InEdgeIt;
+    class InEdgeIt : public Graph::InEdgeIt { 
+    public:
+      InEdgeIt() { }
+      InEdgeIt(const typename Graph::InEdgeIt& e) : Graph::InEdgeIt(e) { }
+      InEdgeIt(const Invalid& i) : Graph::InEdgeIt(i) { }
+      InEdgeIt(const TrivGraphWrapper<Graph>& _G, const Node& n) : 
+	Graph::InEdgeIt(*(_G.graph), n) { }
+    };
+    //typedef typename Graph::SymEdgeIt SymEdgeIt;
+    //typedef typename Graph::EdgeIt EdgeIt;
+    class EdgeIt : public Graph::EdgeIt { 
+    public:
+      EdgeIt() { }
+      EdgeIt(const typename Graph::EdgeIt& e) : Graph::EdgeIt(e) { }
+      EdgeIt(const Invalid& i) : Graph::EdgeIt(i) { }
+      EdgeIt(const TrivGraphWrapper<Graph>& _G) : 
+	Graph::EdgeIt(*(_G.graph)) { }
+    };
+
+    //TrivGraphWrapper() : graph(0) { }
+    TrivGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//    void setGraph(Graph& _graph) { graph = &_graph; }
+//    Graph& getGraph() const { return (*graph); }
+
+    NodeIt& first(NodeIt& i) const { 
+      i=NodeIt(*this);
+      return i;
+    }
+    EdgeIt& first(EdgeIt& i) const { 
+      i=EdgeIt(*this);
+      return i;
+    }
+//     template<typename I> I& first(I& i) const { 
+//       //return graph->first(i); 
+//       i=I(*this);
+//       return i;
+//     }
+    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
+      i=OutEdgeIt(*this, p);
+      return i;
+    }
+    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
+      i=InEdgeIt(*this, p);
+      return i;
+    }
+//     template<typename I, typename P> I& first(I& i, const P& p) const { 
+//       //return graph->first(i, p);
+//       i=I(*this, p);
+//       return i;
+//     }
+    
+//    template<typename I> I getNext(const I& i) const { 
+//      return graph->getNext(i); }
+    template<typename I> I& next(I &i) const { graph->next(i); return i; }    
+
+    template< typename It > It first() const { 
+      It e; first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; first(e, v); return e; }
+
+    Node head(const Edge& e) const { return graph->head(e); }
+    Node tail(const Edge& e) const { return graph->tail(e); }
+
+    template<typename I> bool valid(const I& i) const 
+      { return graph->valid(i); }
+  
+    //template<typename I> void setInvalid(const I &i);
+    //{ return graph->setInvalid(i); }
+
+    int nodeNum() const { return graph->nodeNum(); }
+    int edgeNum() const { return graph->edgeNum(); }
+  
+    template<typename I> Node aNode(const I& e) const { 
+      return graph->aNode(e); }
+    template<typename I> Node bNode(const I& e) const { 
+      return graph->bNode(e); }
+  
+    Node addNode() const { return graph->addNode(); }
+    Edge addEdge(const Node& tail, const Node& head) const { 
+      return graph->addEdge(tail, head); }
+  
+    template<typename I> void erase(const I& i) const { graph->erase(i); }
+  
+    void clear() const { graph->clear(); }
+    
+    template<typename T> class NodeMap : public Graph::NodeMap<T> { 
+    public:
+      NodeMap(const TrivGraphWrapper<Graph>& _G) :  
+	Graph::NodeMap<T>(*(_G.graph)) { }
+      NodeMap(const TrivGraphWrapper<Graph>& _G, T a) : 
+	Graph::NodeMap<T>(*(_G.graph), a) { }
+    };
+
+    template<typename T> class EdgeMap : public Graph::EdgeMap<T> { 
+    public:
+      EdgeMap(const TrivGraphWrapper<Graph>& _G) :  
+	Graph::EdgeMap<T>(*(_G.graph)) { }
+      EdgeMap(const TrivGraphWrapper<Graph>& _G, T a) : 
+	Graph::EdgeMap<T>(*(_G.graph), a) { }
+    };
+
+    template<typename Map, typename T> class NodeMapWrapper {
+    protected:
+      Map* map;
+    public:
+      NodeMapWrapper(Map& _map) : map(&_map) { }
+      //template<typename T> 
+      void set(Node n, T a) { map->set(n, a); }
+      //template<typename T>
+      T get(Node n) const { return map->get(n); }
+    };
+
+    template<typename Map, typename T> class EdgeMapWrapper {
+    protected:
+      Map* map;
+    public:
+      EdgeMapWrapper(Map& _map) : map(&_map) { }
+      //template<typename T> 
+      void set(Edge n, T a) { map->set(n, a); }
+      //template<typename T>
+      T get(Edge n) const { return map->get(n); }
+    };
+  };
+
+  template<typename GraphWrapper>
+  class GraphWrapperSkeleton {
+  protected:
+    GraphWrapper gw;
+  
+  public:
+    //typedef typename GraphWrapper::BaseGraph BaseGraph;
+
+//     typedef typename GraphWrapper::Node Node;
+//     typedef typename GraphWrapper::NodeIt NodeIt;
+
+//     typedef typename GraphWrapper::Edge Edge;
+//     typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+//     typedef typename GraphWrapper::InEdgeIt InEdgeIt;
+//     //typedef typename GraphWrapper::SymEdgeIt SymEdgeIt;
+//     typedef typename GraphWrapper::EdgeIt EdgeIt;
+
+    typedef typename GraphWrapper::Node Node;
+    class NodeIt : public GraphWrapper::NodeIt { 
+    public:
+      NodeIt() { }
+      NodeIt(const typename GraphWrapper::NodeIt& n) : 
+	GraphWrapper::NodeIt(n) { }
+      NodeIt(const Invalid& i) : GraphWrapper::NodeIt(i) { }
+      NodeIt(const GraphWrapperSkeleton<GraphWrapper>& _G) : 
+	GraphWrapper::NodeIt(_G.gw) { }
+    };
+    typedef typename GraphWrapper::Edge Edge;
+    //typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    class OutEdgeIt : public GraphWrapper::OutEdgeIt { 
+    public:
+      OutEdgeIt() { }
+      OutEdgeIt(const typename GraphWrapper::OutEdgeIt& e) : 
+	GraphWrapper::OutEdgeIt(e) { }
+      OutEdgeIt(const Invalid& i) : GraphWrapper::OutEdgeIt(i) { }
+      OutEdgeIt(const GraphWrapperSkeleton<GraphWrapper>& _G, const Node& n) : 
+	GraphWrapper::OutEdgeIt(_G.gw, n) { }
+    };
+    //typedef typename GraphWrapper::InEdgeIt InEdgeIt;
+    class InEdgeIt : public GraphWrapper::InEdgeIt { 
+    public:
+      InEdgeIt() { }
+      InEdgeIt(const typename GraphWrapper::InEdgeIt& e) : 
+	GraphWrapper::InEdgeIt(e) { }
+      InEdgeIt(const Invalid& i) : GraphWrapper::InEdgeIt(i) { }
+      InEdgeIt(const GraphWrapperSkeleton<GraphWrapper>& _G, const Node& n) : 
+	GraphWrapper::InEdgeIt(_G.gw, n) { }
+    };
+    //typedef typename GraphWrapper::SymEdgeIt SymEdgeIt;
+    //typedef typename GraphWrapper::EdgeIt EdgeIt;
+    class EdgeIt : public GraphWrapper::EdgeIt { 
+    public:
+      EdgeIt() { }
+      EdgeIt(const typename GraphWrapper::EdgeIt& e) : 
+	GraphWrapper::EdgeIt(e) { }
+      EdgeIt(const Invalid& i) : GraphWrapper::EdgeIt(i) { }
+      EdgeIt(const GraphWrapperSkeleton<GraphWrapper>& _G) : 
+	GraphWrapper::EdgeIt(_G.gw) { }
+    };
+
+
+    //GraphWrapperSkeleton() : gw() { }
+    GraphWrapperSkeleton(GraphWrapper _gw) : gw(_gw) { }
+
+    //void setGraph(BaseGraph& _graph) { gw.setGraph(_graph); }
+    //BaseGraph& getGraph() const { return gw.getGraph(); }
+    
+    template<typename I> I& first(I& i) const {       
+      i=I(*this);
+      return i;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      i=I(*this, p);
+      return i; 
+    }
+    
+//    template<typename I> I getNext(const I& i) const { return gw.getNext(i); }
+    template<typename I> I& next(I &i) const { gw.next(i); return i; }    
+
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+
+    Node head(const Edge& e) const { return gw.head(e); }
+    Node tail(const Edge& e) const { return gw.tail(e); }
+
+    template<typename I> bool valid(const I& i) const { return gw.valid(i); }
+  
+    //template<typename I> void setInvalid(const I &i);
+    //{ return graph->setInvalid(i); }
+
+    int nodeNum() const { return gw.nodeNum(); }
+    int edgeNum() const { return gw.edgeNum(); }
+  
+    template<typename I> Node aNode(const I& e) const { return gw.aNode(e); }
+    template<typename I> Node bNode(const I& e) const { return gw.bNode(e); }
+  
+    Node addNode() const { return gw.addNode(); }
+    Edge addEdge(const Node& tail, const Node& head) const { 
+      return gw.addEdge(tail, head); }
+  
+    template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+    void clear() const { gw.clear(); }
+    
+    template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+    public:
+      NodeMap(const GraphWrapperSkeleton<GraphWrapper>& _G) :  
+	GraphWrapper::NodeMap<T>(_G.gw) { }
+      NodeMap(const GraphWrapperSkeleton<GraphWrapper>& _G, T a) : 
+	GraphWrapper::NodeMap<T>(_G.gw, a) { }
+    };
+
+    template<typename T> class EdgeMap : public GraphWrapper::EdgeMap<T> { 
+    public:
+      EdgeMap(const GraphWrapperSkeleton<GraphWrapper>& _G) :  
+	GraphWrapper::EdgeMap<T>(_G.gw) { }
+      EdgeMap(const GraphWrapperSkeleton<GraphWrapper>& _G, T a) : 
+	GraphWrapper::EdgeMap<T>(_G.gw, a) { }
+    };
+  };
+
+//   template<typename Graph>
+//   class RevGraphWrapper
+//   {
+//   protected:
+//     Graph* graph;
+  
+//   public:
+//     typedef Graph BaseGraph;
+
+//     typedef typename Graph::Node Node;    
+//     typedef typename Graph::NodeIt NodeIt;
+  
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt InEdgeIt;
+//     typedef typename Graph::InEdgeIt OutEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename Graph::EdgeIt EdgeIt;
+
+//     //RevGraphWrapper() : graph(0) { }
+//     RevGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//     void setGraph(Graph& _graph) { graph = &_graph; }
+//     Graph& getGraph() const { return (*graph); }
+    
+//     template<typename I> I& first(I& i) const { return graph->first(i); }
+//     template<typename I, typename P> I& first(I& i, const P& p) const { 
+//       return graph->first(i, p); }
+
+//     template<typename I> I getNext(const I& i) const { 
+//       return graph->getNext(i); }
+//     template<typename I> I& next(I &i) const { return graph->next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return graph->tail(e); }
+//     Node tail(const Edge& e) const { return graph->head(e); }
+  
+//     template<typename I> bool valid(const I& i) const 
+//       { return graph->valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return graph->aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return graph->bNode(e); }
+
+//     Node addNode() const { return graph->addNode(); }
+//     Edge addEdge(const Node& tail, const Node& head) const { 
+//       return graph->addEdge(tail, head); }
+  
+//     int nodeNum() const { return graph->nodeNum(); }
+//     int edgeNum() const { return graph->edgeNum(); }
+  
+//     template<typename I> void erase(const I& i) const { graph->erase(i); }
+  
+//     void clear() const { graph->clear(); }
+
+//     template<typename T> class NodeMap : public Graph::NodeMap<T> { 
+//     public:
+//       NodeMap(const RevGraphWrapper<Graph>& _G) : 
+// 	Graph::NodeMap<T>(_G.getGraph()) { }
+//       NodeMap(const RevGraphWrapper<Graph>& _G, T a) : 
+// 	Graph::NodeMap<T>(_G.getGraph(), a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public Graph::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const RevGraphWrapper<Graph>& _G) : 
+// 	Graph::EdgeMap<T>(_G.getGraph()) { }
+//       EdgeMap(const RevGraphWrapper<Graph>& _G, T a) : 
+// 	Graph::EdgeMap<T>(_G.getGraph(), a) { }
+//     };
+//   };
+
+//   template<typename /*Graph*/GraphWrapper
+//   /*=typename GraphWrapperSkeleton< TrivGraphWrapper<Graph>*/ >
+//   class RevGraphWrapper : 
+//     public GraphWrapper/*GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/ {
+//   protected:
+//     //Graph* graph;
+    
+//   public:
+//     //typedef Graph BaseGraph;
+
+//     //typedef typename Graph::Node Node;    
+//     //typedef typename Graph::NodeIt NodeIt;
+  
+//     //typedef typename Graph::Edge Edge;
+//     typedef typename GraphWrapper/*typename GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/::OutEdgeIt InEdgeIt;
+//     typedef typename GraphWrapper/*typename GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/::InEdgeIt OutEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename Graph::EdgeIt EdgeIt;
+
+//     //RevGraphWrapper() : graph(0) { }
+//     RevGraphWrapper(GraphWrapper _gw/*BaseGraph& _graph*/) : GraphWrapper/*GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/(_gw/*TrivGraphWrapper<Graph>(_graph)*/) { }
+    
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+    
+//     //template<typename I> I& first(I& i) const { return graph->first(i); }
+//     //template<typename I, typename P> I& first(I& i, const P& p) const { 
+//     //  return graph->first(i, p); }
+
+//     //template<typename I> I getNext(const I& i) const { 
+//     //  return graph->getNext(i); }
+//     //template<typename I> I& next(I &i) const { return graph->next(i); }    
+
+//     //template< typename It > It first() const { 
+//     //  It e; first(e); return e; }
+
+//     //template< typename It > It first(const Node& v) const { 
+//     //  It e; first(e, v); return e; }
+
+//     //Node head(const Edge& e) const { return graph->tail(e); }
+//     //Node tail(const Edge& e) const { return graph->head(e); }
+  
+//     //template<typename I> bool valid(const I& i) const 
+//     //  { return graph->valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+  
+//     //template<typename I> Node aNode(const I& e) const { 
+//     //  return graph->aNode(e); }
+//     //template<typename I> Node bNode(const I& e) const { 
+//     //  return graph->bNode(e); }
+
+//     //Node addNode() const { return graph->addNode(); }
+//     //Edge addEdge(const Node& tail, const Node& head) const { 
+//     //  return graph->addEdge(tail, head); }
+  
+//     //int nodeNum() const { return graph->nodeNum(); }
+//     //int edgeNum() const { return graph->edgeNum(); }
+  
+//     //template<typename I> void erase(const I& i) const { graph->erase(i); }
+  
+//     //void clear() const { graph->clear(); }
+
+//     template<typename T> class NodeMap : 
+//       public GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::NodeMap<T> 
+//     { 
+//     public:
+//       NodeMap(const RevGraphWrapper<GraphWrapper>& _gw) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::NodeMap<T>(_gw) { }
+//       NodeMap(const RevGraphWrapper<GraphWrapper>& _gw, T a) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::NodeMap<T>(_gw, a) { }
+//     };
+    
+//     template<typename T> class EdgeMap : 
+//       public GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const RevGraphWrapper<GraphWrapper>& _gw) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::EdgeMap<T>(_gw) { }
+//       EdgeMap(const RevGraphWrapper<GraphWrapper>& _gw, T a) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::EdgeMap<T>(_gw, a) { }
+//     };
+//   };
+
+  template<typename GraphWrapper>
+  class RevGraphWrapper : public GraphWrapperSkeleton<GraphWrapper> {
+  public:
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Edge Edge;
+    //FIXME 
+    //If GraphWrapper::OutEdgeIt is not defined
+    //and we do not want to use RevGraphWrapper::InEdgeIt,
+    //this won't work, because of typedef
+    //OR
+    //graphs have to define their non-existing iterators to void
+    //Unfortunately all the typedefs are instantiated in templates, 
+    //unlike other stuff
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::OutEdgeIt InEdgeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::InEdgeIt OutEdgeIt;
+
+    RevGraphWrapper(GraphWrapper _gw) : 
+      GraphWrapperSkeleton<GraphWrapper>(_gw) { }  
+
+    Node head(const Edge& e) const 
+      { return GraphWrapperSkeleton<GraphWrapper>::tail(e); }
+    Node tail(const Edge& e) const 
+      { return GraphWrapperSkeleton<GraphWrapper>::head(e); }
+  };
+
+  //Subgraph on the same node-set and partial edge-set
+  template<typename GraphWrapper, typename EdgeFilterMap>
+  class SubGraphWrapper : public GraphWrapperSkeleton<GraphWrapper> {
+  protected:
+    EdgeFilterMap* filter_map;
+  public:
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::NodeIt NodeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Edge Edge;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::EdgeIt EdgeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::InEdgeIt InEdgeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::OutEdgeIt OutEdgeIt;
+
+    SubGraphWrapper(GraphWrapper _gw, EdgeFilterMap& _filter_map) : 
+      GraphWrapperSkeleton<GraphWrapper>(_gw), filter_map(&_filter_map) { }  
+
+    template<typename I> I& first(I& i) const { 
+      gw.first(i); 
+      while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      gw.first(i, p); 
+      while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    
+    //template<typename I> I getNext(const I& i) const { 
+    //  return gw.getNext(i); 
+    //}
+    template<typename I> I& next(I &i) const { 
+      gw.next(i); 
+      while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+    
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+  };
+
+//   template<typename GraphWrapper>
+//   class UndirGraphWrapper {
+//   protected:
+//     //Graph* graph;
+//     GraphWrapper gw;
+
+//   public:
+//     typedef GraphWrapper BaseGraph;
+
+//     typedef typename GraphWrapper::Node Node;
+//     typedef typename GraphWrapper::NodeIt NodeIt;
+
+//     //typedef typename Graph::Edge Edge;
+//     //typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     //typedef typename Graph::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename Graph::EdgeIt EdgeIt;
+
+//     //private:
+//     typedef typename GraphWrapper::Edge GraphEdge;
+//     typedef typename GraphWrapper::OutEdgeIt GraphOutEdgeIt;
+//     typedef typename GraphWrapper::InEdgeIt GraphInEdgeIt;
+//     //public:
+
+//     //UndirGraphWrapper() : graph(0) { }
+//     UndirGraphWrapper(GraphWrapper _gw) : gw(_gw) { }
+
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+  
+//     class Edge {
+//       friend class UndirGraphWrapper<GraphWrapper>;
+//       bool out_or_in; //true iff out
+//       GraphOutEdgeIt out;
+//       GraphInEdgeIt in;
+//     public:
+//       Edge() : out_or_in(), out(), in() { }
+//       Edge(const Invalid& i) : out_or_in(false), out(), in(i) { }
+//       operator GraphEdge() const {
+// 	if (out_or_in) return(out); else return(in);
+//       }
+//       friend bool operator==(const Edge& u, const Edge& v) { 
+// 	if (v.out_or_in) 
+// 	  return (u.out_or_in && u.out==v.out);
+// 	else
+// 	  return (!u.out_or_in && u.in==v.in);
+//       } 
+//       friend bool operator!=(const Edge& u, const Edge& v) { 
+// 	if (v.out_or_in) 
+// 	  return (!u.out_or_in || u.out!=v.out);
+// 	else
+// 	  return (u.out_or_in || u.in!=v.in);
+//       } 
+//     };
+
+//     class OutEdgeIt : public Edge {
+//       friend class UndirGraphWrapper<GraphWrapper>;
+//     public:
+//       OutEdgeIt() : Edge() { }
+//       OutEdgeIt(const Invalid& i) : Edge(i) { }
+//       OutEdgeIt(const UndirGraphWrapper<GraphWrapper>& _G, const Node& n) 
+// 	: Edge() { 
+// 	out_or_in=true;
+// 	_G.gw.first(out, n);
+// 	if (!(_G.gw.valid(out))) {
+// 	  out_or_in=false;
+// 	  _G.gw.first(in, n);
+// 	}
+//       }
+//     };
+
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+//       e.out_or_in=true;
+//       gw.first(e.out, n);
+//       if (!(gw.valid(e.out))) {
+// 	e.out_or_in=false;
+// 	gw.first(e.in, n);
+//       }
+//       return e;
+//     }
+
+//     OutEdgeIt& next(OutEdgeIt& e) const {
+//       if (e.out_or_in) {
+// 	Node n=gw.tail(e.out);
+// 	gw.next(e.out);
+// 	if (!gw.valid(e.out)) {
+// 	  e.out_or_in=false;
+// 	  gw.first(e.in, n);
+// 	}
+//       } else {
+// 	gw.next(e.in);
+//       }
+//       return e;
+//     }
+
+//     Node aNode(const OutEdgeIt& e) const { 
+//       if (e.out_or_in) return gw.tail(e); else return gw.head(e); }
+//     Node bNode(const OutEdgeIt& e) const { 
+//       if (e.out_or_in) return gw.head(e); else return gw.tail(e); }
+
+//     typedef OutEdgeIt InEdgeIt; 
+
+//     template<typename I> I& first(I& i) const { return gw.first(i); }
+// //     template<typename I, typename P> I& first(I& i, const P& p) const { 
+// //       return graph->first(i, p); }
+    
+//     template<typename I> I getNext(const I& i) const { 
+//       return gw.getNext(i); }
+//     template<typename I> I& next(I &i) const { return gw.next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return gw.head(e); }
+//     Node tail(const Edge& e) const { return gw.tail(e); }
+
+//     template<typename I> bool valid(const I& i) const 
+//       { return gw.valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+
+//     int nodeNum() const { return gw.nodeNum(); }
+//     int edgeNum() const { return gw.edgeNum(); }
+  
+// //     template<typename I> Node aNode(const I& e) const { 
+// //       return graph->aNode(e); }
+// //     template<typename I> Node bNode(const I& e) const { 
+// //       return graph->bNode(e); }
+  
+//     Node addNode() const { return gw.addNode(); }
+// // FIXME: ez igy nem jo, mert nem
+// //    Edge addEdge(const Node& tail, const Node& head) const { 
+// //      return graph->addEdge(tail, head); }
+  
+//     template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//     void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+//     public:
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw) { }
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public GraphWrapper::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapper::EdgeMap<T>(_G.gw) { }
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::EdgeMap<T>(_G.gw, a) { }
+//     };
+//   };
+
+
+  template<typename GraphWrapper>
+  class UndirGraphWrapper : public GraphWrapperSkeleton<GraphWrapper> {
+  protected:
+//    GraphWrapper gw;
+
+  public:
+    //typedef GraphWrapper BaseGraph;
+
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::NodeIt NodeIt;
+
+    //private:
+    //FIXME ezeknek valojaban a GraphWrapper megfelelo dolgai kellene hogy 
+    //legyenek, at kell irni
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/
+    GraphWrapper::Edge GraphEdge;
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/ 
+    GraphWrapper::OutEdgeIt GraphOutEdgeIt;
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/ 
+    GraphWrapper::InEdgeIt GraphInEdgeIt;
+    //public:
+
+    //UndirGraphWrapper() : graph(0) { }
+    UndirGraphWrapper(GraphWrapper _gw) : 
+      GraphWrapperSkeleton<GraphWrapper>(_gw) { }  
+
+    //UndirGraphWrapper(GraphWrapper _gw) : gw(_gw) { }
+
+    //void setGraph(Graph& _graph) { graph = &_graph; }
+    //Graph& getGraph() const { return (*graph); }
+  
+    class Edge {
+      friend class UndirGraphWrapper<GraphWrapper>;
+    protected:
+      bool out_or_in; //true iff out
+      GraphOutEdgeIt out;
+      GraphInEdgeIt in;
+    public:
+      Edge() : out_or_in(), out(), in() { }
+      Edge(const Invalid& i) : out_or_in(false), out(), in(i) { }
+      operator GraphEdge() const {
+	if (out_or_in) return(out); else return(in);
+      }
+//FIXME
+//2 edges are equal if they "refer" to the same physical edge 
+//is it good?
+      friend bool operator==(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  if (u.out_or_in) return (u.out==v.out); else return (u.out==v.in);
+	//return (u.out_or_in && u.out==v.out);
+	else
+	  if (u.out_or_in) return (u.out==v.in); else return (u.in==v.in);
+	//return (!u.out_or_in && u.in==v.in);
+      } 
+      friend bool operator!=(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  if (u.out_or_in) return (u.out!=v.out); else return (u.out!=v.in);
+	//return (!u.out_or_in || u.out!=v.out);
+	else
+	  if (u.out_or_in) return (u.out!=v.in); else return (u.in!=v.in);
+	//return (u.out_or_in || u.in!=v.in);
+      } 
+    };
+
+    class OutEdgeIt : public Edge {
+      friend class UndirGraphWrapper<GraphWrapper>;
+    public:
+      OutEdgeIt() : Edge() { }
+      OutEdgeIt(const Invalid& i) : Edge(i) { }
+      OutEdgeIt(const UndirGraphWrapper<GraphWrapper>& _G, const Node& n) 
+	: Edge() { 
+	out_or_in=true; _G.gw.first(out, n);
+	if (!(_G.gw.valid(out))) { out_or_in=false; _G.gw.first(in, n);	}
+      }
+    };
+
+    typedef OutEdgeIt InEdgeIt; 
+
+    class EdgeIt : public Edge {
+      friend class UndirGraphWrapper<GraphWrapper>;
+    protected:
+      NodeIt v;
+    public:
+      EdgeIt() : Edge() { }
+      EdgeIt(const Invalid& i) : Edge(i) { }
+      EdgeIt(const UndirGraphWrapper<GraphWrapper>& _G) 
+	: Edge() { 
+	out_or_in=true;
+	//Node v;
+	_G.first(v);
+	if (_G.valid(v)) _G.gw.first(out); else out=INVALID;
+	while (_G.valid(v) && !_G.gw.valid(out)) { 
+	  _G.gw.next(v); 
+	  if (_G.valid(v)) _G.gw.first(out); 
+	}
+      }
+    };
+
+    OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+      e.out_or_in=true; gw.first(e.out, n);
+      if (!(gw.valid(e.out))) { e.out_or_in=false; gw.first(e.in, n); }
+      return e;
+    }
+
+    EdgeIt& first(EdgeIt& e) const {
+      e.out_or_in=true;
+      //NodeIt v;
+      first(e.v);
+      if (valid(e.v)) gw.first(e.out, e.v); else e.out=INVALID;
+      while (valid(e.v) && !gw.valid(e.out)) { 
+	gw.next(e.v); 
+	if (valid(e.v)) gw.first(e.out, e.v); 
+      }
+      return e;
+    }
+
+    template<typename I> I& first(I& i) const { gw.first(i); return i; }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      gw.first(i, p); return i; }
+
+    OutEdgeIt& next(OutEdgeIt& e) const {
+      if (e.out_or_in) {
+	Node n=gw.tail(e.out);
+	gw.next(e.out);
+	if (!gw.valid(e.out)) { e.out_or_in=false; gw.first(e.in, n); }
+      } else {
+	gw.next(e.in);
+      }
+      return e;
+    }
+
+    EdgeIt& next(EdgeIt& e) const {
+      //NodeIt v=tail(e);
+      gw.next(e.out);
+      while (valid(e.v) && !gw.valid(e.out)) { 
+	next(e.v); 
+	if (valid(e.v)) gw.first(e.out, e.v); 
+      }
+      return e;
+    }
+
+    template<typename I> I& next(I &i) const { return gw.next(i); }    
+//    template<typename I> I getNext(const I& i) const { return gw.getNext(i); }
+
+    template< typename It > It first() const { 
+      It e; first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; first(e, v); return e; }
+
+//    Node head(const Edge& e) const { return gw.head(e); }
+//    Node tail(const Edge& e) const { return gw.tail(e); }
+
+//    template<typename I> bool valid(const I& i) const 
+//      { return gw.valid(i); }
+  
+//    int nodeNum() const { return gw.nodeNum(); }
+//    int edgeNum() const { return gw.edgeNum(); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return graph->aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return graph->bNode(e); }
+
+    Node aNode(const OutEdgeIt& e) const { 
+      if (e.out_or_in) return gw.tail(e); else return gw.head(e); }
+    Node bNode(const OutEdgeIt& e) const { 
+      if (e.out_or_in) return gw.head(e); else return gw.tail(e); }
+  
+//    Node addNode() const { return gw.addNode(); }
+
+// FIXME: ez igy nem jo, mert nem
+//    Edge addEdge(const Node& tail, const Node& head) const { 
+//      return graph->addEdge(tail, head); }
+  
+//    template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//    void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+//     public:
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw) { }
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : 
+//       public GraphWrapperSkeleton<GraphWrapper>::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapperSkeleton<GraphWrapper>::EdgeMap<T>(_G.gw) { }
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::EdgeMap<T>(_G.gw, a) { }
+//     };
+   };
+
+
+
+
+
+//   template<typename Graph>
+//   class SymGraphWrapper
+//   {
+//     Graph* graph;
+  
+//   public:
+//     typedef Graph BaseGraph;
+
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+  
+//     typedef typename Graph::NodeIt NodeIt;
+    
+//     //FIXME tag-ekkel megcsinalni, hogy abbol csinaljon
+//     //iranyitatlant, ami van
+//     //mert csak 1 dolgot lehet be typedef-elni
+//     typedef typename Graph::OutEdgeIt SymEdgeIt;
+//     //typedef typename Graph::InEdgeIt SymEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename Graph::EdgeIt EdgeIt;
+
+//     int nodeNum() const { return graph->nodeNum(); }
+//     int edgeNum() const { return graph->edgeNum(); }
+    
+//     template<typename I> I& first(I& i) const { return graph->first(i); }
+//     template<typename I, typename P> I& first(I& i, const P& p) const { 
+//       return graph->first(i, p); }
+//     //template<typename I> I next(const I i); { return graph->goNext(i); }
+//     //template<typename I> I &goNext(I &i); { return graph->goNext(i); }
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(Node v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return graph->head(e); }
+//     Node tail(const Edge& e) const { return graph->tail(e); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return graph->aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return graph->bNode(e); }
+  
+//     //template<typename I> bool valid(const I i);
+//     //{ return graph->valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+  
+//     Node addNode() { return graph->addNode(); }
+//     Edge addEdge(const Node& tail, const Node& head) { 
+//       return graph->addEdge(tail, head); }
+  
+//     template<typename I> void erase(const I& i) { graph->erase(i); }
+  
+//     void clear() { graph->clear(); }
+  
+//     template<typename T> class NodeMap : public Graph::NodeMap<T> { };
+//     template<typename T> class EdgeMap : public Graph::EdgeMap<T> { };
+  
+//     void setGraph(Graph& _graph) { graph = &_graph; }
+//     Graph& getGraph() { return (*graph); }
+
+//     //SymGraphWrapper() : graph(0) { }
+//     SymGraphWrapper(Graph& _graph) : graph(&_graph) { }
+//   };
+
+
+  template<typename GraphWrapper, typename Number, typename FlowMap, typename CapacityMap>
+  class ResGraphWrapper : public GraphWrapperSkeleton<GraphWrapper>{
+  public:
+    //typedef Graph BaseGraph;
+    //typedef TrivGraphWrapper<const Graph> GraphWrapper;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::NodeIt NodeIt;
+  private:
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/
+    GraphWrapper::OutEdgeIt OldOutEdgeIt;
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/
+    GraphWrapper::InEdgeIt OldInEdgeIt;
+  protected:
+    //const Graph* graph;
+    //GraphWrapper gw;
+    FlowMap* flow;
+    const CapacityMap* capacity;
+  public:
+
+    ResGraphWrapper(const GraphWrapper& _gw, FlowMap& _flow, 
+		    const CapacityMap& _capacity) : 
+      GraphWrapperSkeleton<GraphWrapper>(_gw), 
+      flow(&_flow), capacity(&_capacity) { }
+
+    //void setGraph(const Graph& _graph) { graph = &_graph; }
+    //const Graph& getGraph() const { return (*graph); }
+
+    class Edge; 
+    class OutEdgeIt; 
+    friend class Edge; 
+    friend class OutEdgeIt; 
+
+    class Edge {
+      friend class ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>;
+    protected:
+      bool out_or_in; //true, iff out
+      OldOutEdgeIt out;
+      OldInEdgeIt in;
+    public:
+      Edge() : out_or_in(true) { } 
+      Edge(const Invalid& i) : out_or_in(false), out(), in(i) { }
+//       bool valid() const { 
+// 	return out_or_in && out.valid() || in.valid(); }
+      friend bool operator==(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  return (u.out_or_in && u.out==v.out);
+	else
+	  return (!u.out_or_in && u.in==v.in);
+      } 
+      friend bool operator!=(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  return (!u.out_or_in || u.out!=v.out);
+	else
+	  return (u.out_or_in || u.in!=v.in);
+      } 
+    };
+
+
+    class OutEdgeIt : public Edge {
+      friend class ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>;
+    public:
+      OutEdgeIt() { }
+      //FIXME
+      OutEdgeIt(const Edge& e) : Edge(e) { }
+      OutEdgeIt(const Invalid& i) : Edge(i) { }
+    protected:
+      OutEdgeIt(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& resG, Node v) : Edge() { 
+	resG.gw.first(out, v);
+	while( resG.gw.valid(out) && !(resG.resCap(out)>0) ) { resG.gw.next(out); }
+	if (!resG.gw.valid(out)) {
+	  out_or_in=0;
+	  resG.gw.first(in, v);
+	  while( resG.gw.valid(in) && !(resG.resCap(in)>0) ) { resG.gw.next(in); }
+	}
+      }
+//     public:
+//       OutEdgeIt& operator++() { 
+// 	if (out_or_in) {
+// 	  Node v=/*resG->*/G->aNode(out);
+// 	  ++out;
+// 	  while( out.valid() && !(Edge::resCap()>0) ) { ++out; }
+// 	  if (!out.valid()) {
+// 	    out_or_in=0;
+// 	    G->first(in, v); 
+// 	    while( in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	  }
+// 	} else {
+// 	  ++in;
+// 	  while( in.valid() && !(Edge::resCap()>0) ) { ++in; } 
+// 	}
+// 	return *this; 
+//       }
+    };
+
+    //FIXME This is just for having InEdgeIt
+    typedef void InEdgeIt;
+
+    class EdgeIt : public Edge {
+      friend class ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>;
+      NodeIt v; 
+    public:
+      EdgeIt() { }
+      //EdgeIt(const EdgeIt& e) : Edge(e), v(e.v) { }
+      EdgeIt(const Invalid& i) : Edge(i) { }
+      EdgeIt(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& resG) : Edge() { 
+	resG.gw.first(v);
+	if (resG.gw.valid(v)) resG.gw.first(out, v); else out=INVALID;
+	while (resG.gw.valid(out) && !(resG.resCap(out)>0) ) { resG.gw.next(out); }
+	while (resG.gw.valid(v) && !resG.gw.valid(out)) { 
+	  resG.gw.next(v); 
+	  if (resG.gw.valid(v)) resG.gw.first(out, v); 
+	  while (resG.gw.valid(out) && !(resG.resCap(out)>0) ) { resG.gw.next(out); }
+	}
+	if (!resG.gw.valid(out)) {
+	  out_or_in=0;
+	  resG.gw.first(v);
+	  if (resG.gw.valid(v)) resG.gw.first(in, v); else in=INVALID;
+	  while (resG.gw.valid(in) && !(resG.resCap(in)>0) ) { resG.gw.next(in); }
+	  while (resG.gw.valid(v) && !resG.gw.valid(in)) { 
+	    resG.gw.next(v); 
+	    if (resG.gw.valid(v)) resG.gw.first(in, v); 
+	    while (resG.gw.valid(in) && !(resG.resCap(in)>0) ) { resG.gw.next(in); }
+	  }
+	}
+      }
+//       EdgeIt& operator++() { 
+// 	if (out_or_in) {
+// 	  ++out;
+// 	  while (out.valid() && !(Edge::resCap()>0) ) { ++out; }
+// 	  while (v.valid() && !out.valid()) { 
+// 	    ++v; 
+// 	    if (v.valid()) G->first(out, v); 
+// 	    while (out.valid() && !(Edge::resCap()>0) ) { ++out; }
+// 	  }
+// 	  if (!out.valid()) {
+// 	    out_or_in=0;
+// 	    G->first(v);
+// 	    if (v.valid()) G->first(in, v); else in=OldInEdgeIt();
+// 	    while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	    while (v.valid() && !in.valid()) { 
+// 	      ++v; 
+// 	      if (v.valid()) G->first(in, v); 
+// 	      while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	    }  
+// 	  }
+// 	} else {
+// 	  ++in;
+// 	  while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	  while (v.valid() && !in.valid()) { 
+// 	    ++v; 
+// 	    if (v.valid()) G->first(in, v); 
+// 	    while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	  }
+// 	}
+// 	return *this;
+//       }
+    };
+
+    NodeIt& first(NodeIt& v) const { gw.first(v); return v; }
+    OutEdgeIt& first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); 
+      return e;
+    }
+    EdgeIt& first(EdgeIt& e) const { 
+      e=EdgeIt(*this); 
+      return e;
+    }
+   
+    NodeIt& next(NodeIt& n) const { return gw.next(n); }
+
+    OutEdgeIt& next(OutEdgeIt& e) const { 
+      if (e.out_or_in) {
+	Node v=gw.aNode(e.out);
+	gw.next(e.out);
+	while( gw.valid(e.out) && !(resCap(e.out)>0) ) { gw.next(e.out); }
+	if (!gw.valid(e.out)) {
+	  e.out_or_in=0;
+	  gw.first(e.in, v); 
+	  while( gw.valid(e.in) && !(resCap(e.in)>0) ) { gw.next(e.in); }
+	}
+      } else {
+	gw.next(e.in);
+	while( gw.valid(e.in) && !(resCap(e.in)>0) ) { gw.next(e.in); } 
+      }
+      return e;
+    }
+
+    EdgeIt& next(EdgeIt& e) const { 
+      if (e.out_or_in) {
+	gw.next(e.out);
+	while (gw.valid(e.out) && !(resCap(e.out)>0) ) { gw.next(e.out); }
+	  while (gw.valid(e.v) && !gw.valid(e.out)) { 
+	    gw.next(e.v); 
+	    if (gw.valid(e.v)) gw.first(e.out, e.v); 
+	    while (gw.valid(e.out) && !(resCap(e.out)>0) ) { gw.next(e.out); }
+	  }
+	  if (!gw.valid(e.out)) {
+	    e.out_or_in=0;
+	    gw.first(e.v);
+	    if (gw.valid(e.v)) gw.first(e.in, e.v); else e.in=INVALID;
+	    while (gw.valid(e.in) && !(resCap(e.in)>0) ) { gw.next(e.in); }
+	    while (gw.valid(e.v) && !gw.valid(e.in)) { 
+	      gw.next(e.v); 
+	      if (gw.valid(e.v)) gw.first(e.in, e.v); 
+	      while (gw.valid(e.in) && !(resCap(e.in)>0) ) { gw.next(e.in); }
+	    }  
+	  }
+	} else {
+	  gw.next(e.in);
+	  while (gw.valid(e.in) && !(resCap(e.in)>0) ) { gw.next(e.in); }
+	  while (gw.valid(e.v) && !gw.valid(e.in)) { 
+	    gw.next(e.v); 
+	    if (gw.valid(e.v)) gw.first(e.in, e.v); 
+	    while (gw.valid(e.in) && !(resCap(e.in)>0) ) { gw.next(e.in); }
+	  }
+	}
+	return e;
+      }
+    
+
+    template< typename It >
+    It first() const { 
+      It e;
+      first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      first(e, v);
+      return e; 
+    }
+
+    Node tail(Edge e) const { 
+      return ((e.out_or_in) ? gw.aNode(e.out) : gw.aNode(e.in)); }
+    Node head(Edge e) const { 
+      return ((e.out_or_in) ? gw.bNode(e.out) : gw.bNode(e.in)); }
+
+    Node aNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? gw.aNode(e.out) : gw.aNode(e.in)); }
+    Node bNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? gw.bNode(e.out) : gw.bNode(e.in)); }
+
+    int nodeNum() const { return gw.nodeNum(); }
+    //FIXME
+    //int edgeNum() const { return gw.edgeNum(); }
+
+
+    int id(Node v) const { return gw.id(v); }
+
+    bool valid(Node n) const { return gw.valid(n); }
+    bool valid(Edge e) const { 
+      return e.out_or_in ? gw.valid(e.out) : gw.valid(e.in); }
+
+    void augment(const Edge& e, Number a) const {
+      if (e.out_or_in)  
+	flow->set(e.out, flow->get(e.out)+a);
+      else  
+	flow->set(e.in, flow->get(e.in)-a);
+    }
+
+    Number resCap(const Edge& e) const { 
+      if (e.out_or_in) 
+	return (capacity->get(e.out)-flow->get(e.out)); 
+      else 
+	return (flow->get(e.in)); 
+    }
+
+    Number resCap(OldOutEdgeIt out) const { 
+      return (capacity->get(out)-flow->get(out)); 
+    }
+    
+    Number resCap(OldInEdgeIt in) const { 
+      return (flow->get(in)); 
+    }
+
+//     template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+//     public:
+//       NodeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G) 
+// 	: GraphWrapper::NodeMap<T>(_G.gw) { }
+//       NodeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G, 
+// 	      T a) : GraphWrapper::NodeMap<T>(_G.gw, a) { }
+//     };
+
+//     template <typename T>
+//     class NodeMap {
+//       typename Graph::NodeMap<T> node_map; 
+//     public:
+//       NodeMap(const ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(*(_G.graph)) { }
+//       NodeMap(const ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G, T a) : node_map(*(_G.graph), a) { }
+//       void set(Node nit, T a) { node_map.set(nit, a); }
+//       T get(Node nit) const { return node_map.get(nit); }
+//     };
+
+    template <typename T>
+    class EdgeMap {
+      typename GraphWrapper::EdgeMap<T> forward_map, backward_map; 
+    public:
+      EdgeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G) : forward_map(_G.gw), backward_map(_G.gw) { }
+      EdgeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G, T a) : forward_map(_G.gw, a), backward_map(_G.gw, a) { }
+      void set(Edge e, T a) { 
+	if (e.out_or_in) 
+	  forward_map.set(e.out, a); 
+	else 
+	  backward_map.set(e.in, a); 
+      }
+      T get(Edge e) { 
+	if (e.out_or_in) 
+	  return forward_map.get(e.out); 
+	else 
+	  return backward_map.get(e.in); 
+      }
+    };
+  };
+
+  //Subgraph on the same node-set and partial edge-set
+  template<typename GraphWrapper, typename FirstOutEdgesMap>
+  class ErasingFirstGraphWrapper : public GraphWrapperSkeleton<GraphWrapper> {
+  protected:
+    FirstOutEdgesMap* first_out_edges;
+  public:
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::NodeIt NodeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::Edge Edge;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::EdgeIt EdgeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::InEdgeIt InEdgeIt;
+    typedef typename GraphWrapperSkeleton<GraphWrapper>::OutEdgeIt OutEdgeIt;
+
+    ErasingFirstGraphWrapper(GraphWrapper _gw, FirstOutEdgesMap& _first_out_edges) : 
+      GraphWrapperSkeleton<GraphWrapper>(_gw), first_out_edges(&_first_out_edges) { }  
+
+    template<typename I> I& first(I& i) const { 
+      gw.first(i); 
+      //while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+      e=first_out_edges->get(n);
+      return e;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      gw.first(i, p); 
+      //while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    
+    //template<typename I> I getNext(const I& i) const { 
+    //  return gw.getNext(i); 
+    //}
+    template<typename I> I& next(I &i) const { 
+      gw.next(i); 
+      //while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+    
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+
+    void erase(const OutEdgeIt& e) const {
+      OutEdgeIt f=e;
+      this->next(f);
+      first_out_edges->set(this->tail(e), f);
+    }
+  };
+
+//   template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+//   class ErasingResGraphWrapper : public ResGraphWrapper<Graph, Number, FlowMap, CapacityMap> {
+//   protected:
+//     ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt> first_out_edges;
+//     //ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<int> dist;
+//   public:
+//     ErasingResGraphWrapper(const Graph& _G, FlowMap& _flow, 
+// 			   const CapacityMap& _capacity) : 
+//       ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>(_G, _flow, _capacity), 
+//       first_out_edges(*this) /*, dist(*this)*/ { 
+//       for(NodeIt n=this->template first<NodeIt>(); this->valid(n); this->next(n)) {
+// 	OutEdgeIt e;
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(e, n);
+// 	first_out_edges.set(n, e);
+//       }
+//     }
+
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+  
+//     //TrivGraphWrapper() : graph(0) { }
+//     //ErasingResGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//     //typedef Graph BaseGraph;
+
+//     //typedef typename Graph::Node Node;
+//     //typedef typename Graph::NodeIt NodeIt;
+
+//     //typedef typename Graph::Edge Edge;
+//     //typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     //typedef typename Graph::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename Graph::EdgeIt EdgeIt;
+
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Node Node;
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeIt NodeIt;
+
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Edge Edge;
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt OutEdgeIt;
+//     //typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeIt EdgeIt;
+
+//     NodeIt& first(NodeIt& n) const { 
+//       return ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(n);
+//     }
+
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const { 
+//       e=first_out_edges.get(n);
+//       return e;
+//     }
+    
+//     //ROSSZ template<typename I> I& first(I& i) const { return first(i); }
+//     //ROSSZ template<typename I, typename P> I& first(I& i, const P& p) const { 
+//     //  return first(i, p); }
+    
+//     //template<typename I> I getNext(const I& i) const { 
+//     //  return gw.getNext(i); }
+//     //template<typename I> I& next(I &i) const { return gw.next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     //Node head(const Edge& e) const { return gw.head(e); }
+//     //Node tail(const Edge& e) const { return gw.tail(e); }
+
+//     //template<typename I> bool valid(const I& i) const 
+//     //  { return gw.valid(i); }
+  
+//     //int nodeNum() const { return gw.nodeNum(); }
+//     //int edgeNum() const { return gw.edgeNum(); }
+  
+//     //template<typename I> Node aNode(const I& e) const { 
+//     //  return gw.aNode(e); }
+//     //template<typename I> Node bNode(const I& e) const { 
+//     //  return gw.bNode(e); }
+  
+//     //Node addNode() const { return gw.addNode(); }
+//     //Edge addEdge(const Node& tail, const Node& head) const { 
+//     //  return gw.addEdge(tail, head); }
+  
+//     //void erase(const OutEdgeIt& e) {
+//     //  first_out_edge(this->tail(e))=e;
+//     //}
+//     void erase(const Edge& e) {
+//       OutEdgeIt f(e);
+//       next(f);
+//       first_out_edges.set(this->tail(e), f);
+//     }
+//     //template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//     //void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T> { 
+//     public:
+//       NodeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/) { }
+//       NodeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G, T a) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/) { }
+//       EdgeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G, T a) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+//   };
+
+//   template<typename GraphWrapper> 
+//   class FilterGraphWrapper {
+//   };
+
+//   template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+//   class FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > : public ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> {
+
+//     //Graph* graph;
+  
+//   public:
+//     //typedef Graph BaseGraph;
+
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Node Node;
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeIt NodeIt;
+
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Edge Edge;
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt OutEdgeIt;
+//     //typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeIt EdgeIt;
+
+//     //FilterGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt> first_out_edges;
+    
+//   public:
+//     FilterGraphWrapper(const Graph& _G, FlowMap& _flow, 
+// 			   const CapacityMap& _capacity) : 
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>(_G, _flow, _capacity), dist(*this, gw.nodeNum()) { 
+//     }
+
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(e, n);
+//       while (valid(e) && (dist.get(tail(e))/*+1!=*/>=dist.get(head(e)))) 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//       return e;
+//     }
+
+//     NodeIt& next(NodeIt& e) const {
+//       return ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//     }
+
+//     OutEdgeIt& next(OutEdgeIt& e) const {
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//       while (valid(e) && (dist.get(tail(e))/*+1!*/>=dist.get(head(e)))) 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//       return e;
+//     }
+
+//     NodeIt& first(NodeIt& n) const {
+//       return ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(n);
+//     }
+
+//     void erase(const Edge& e) {
+//       OutEdgeIt f(e);
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(f);
+//       while (valid(f) && (dist.get(tail(f))/*+1!=*/>=dist.get(head(f)))) 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(f);
+//       first_out_edges.set(this->tail(e), f);
+//     }
+
+//     //TrivGraphWrapper() : graph(0) { }
+//     //TrivGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+    
+//     //template<typename I> I& first(I& i) const { return gw.first(i); }
+//     //template<typename I, typename P> I& first(I& i, const P& p) const { 
+//     //  return gw.first(i, p); }
+    
+//     //template<typename I> I getNext(const I& i) const { 
+//     //  return gw.getNext(i); }
+//     //template<typename I> I& next(I &i) const { return gw.next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     //Node head(const Edge& e) const { return gw.head(e); }
+//     //Node tail(const Edge& e) const { return gw.tail(e); }
+
+//     //template<typename I> bool valid(const I& i) const 
+//     //  { return gw.valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return gw.setInvalid(i); }
+
+//     //int nodeNum() const { return gw.nodeNum(); }
+//     //int edgeNum() const { return gw.edgeNum(); }
+  
+//     //template<typename I> Node aNode(const I& e) const { 
+//     //  return gw.aNode(e); }
+//     //template<typename I> Node bNode(const I& e) const { 
+//     //  return gw.bNode(e); }
+  
+//     //Node addNode() const { return gw.addNode(); }
+//     //Edge addEdge(const Node& tail, const Node& head) const { 
+//     //  return gw.addEdge(tail, head); }
+  
+//     //template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//     //void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T> { 
+//     public:
+//       NodeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/) { }
+//       NodeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G, T a) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/) { }
+//       EdgeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G, T a) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+
+//   public:
+//     ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<int> dist;
+
+//   };
+
+
+
+// // FIXME: comparison should be made better!!!
+//   template<typename Graph, typename T, typename LowerMap, typename FlowMap, typename UpperMap>
+//   class ResGraphWrapper
+//   {
+//     Graph* graph;
+  
+//   public:
+//     typedef Graph BaseGraph;
+
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+  
+//     typedef typename Graph::NodeIt NodeIt;
+   
+//     class OutEdgeIt {
+//     public:
+//       //Graph::Node n;
+//       bool out_or_in;
+//       typename Graph::OutEdgeIt o;
+//       typename Graph::InEdgeIt i;   
+//     };
+//     class InEdgeIt {
+//     public:
+//       //Graph::Node n;
+//       bool out_or_in;
+//       typename Graph::OutEdgeIt o;
+//       typename Graph::InEdgeIt i;   
+//     };
+//     typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename Graph::EdgeIt EdgeIt;
+
+//     int nodeNum() const { return gw.nodeNum(); }
+//     int edgeNum() const { return gw.edgeNum(); }
+
+//     Node& first(Node& n) const { return gw.first(n); }
+
+//     // Edge and SymEdge  is missing!!!!
+//     // Edge <-> In/OutEdgeIt conversion is missing!!!!
+
+//     //FIXME
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const 
+//       {
+// 	e.n=n;
+// 	gw.first(e.o,n);
+// 	while(gw.valid(e.o) && fmap.get(e.o)>=himap.get(e.o))
+// 	  gw.goNext(e.o);
+// 	if(!gw.valid(e.o)) {
+// 	  gw.first(e.i,n);
+// 	  while(gw.valid(e.i) && fmap.get(e.i)<=lomap.get(e.i))
+// 	    gw.goNext(e.i);
+// 	}
+// 	return e;
+//       }
+// /*
+//   OutEdgeIt &goNext(OutEdgeIt &e)
+//   {
+//   if(gw.valid(e.o)) {
+//   while(gw.valid(e.o) && fmap.get(e.o)>=himap.get(e.o))
+//   gw.goNext(e.o);
+//   if(gw.valid(e.o)) return e;
+//   else gw.first(e.i,e.n);
+//   }
+//   else {
+//   while(gw.valid(e.i) && fmap.get(e.i)<=lomap.get(e.i))
+//   gw.goNext(e.i);
+//   return e;
+//   }
+//   }
+//   OutEdgeIt Next(const OutEdgeIt &e) {OutEdgeIt t(e); return goNext(t);}
+// */
+//     //bool valid(const OutEdgeIt e) { return gw.valid(e.o)||gw.valid(e.i);}
+
+//     //FIXME
+//     InEdgeIt& first(InEdgeIt& e, const Node& n) const 
+//       {
+// 	e.n=n;
+// 	gw.first(e.i,n);
+// 	while(gw.valid(e.i) && fmap.get(e.i)>=himap.get(e.i))
+// 	  gw.goNext(e.i);
+// 	if(!gw.valid(e.i)) {
+// 	  gw.first(e.o,n);
+// 	  while(gw.valid(e.o) && fmap.get(e.o)<=lomap.get(e.o))
+// 	    gw.goNext(e.o);
+// 	}
+// 	return e;
+//       }
+// /*
+//   InEdgeIt &goNext(InEdgeIt &e)
+//   {
+//   if(gw.valid(e.i)) {
+//   while(gw.valid(e.i) && fmap.get(e.i)>=himap.get(e.i))
+//   gw.goNext(e.i);
+//   if(gw.valid(e.i)) return e;
+//   else gw.first(e.o,e.n);
+//   }
+//   else {
+//   while(gw.valid(e.o) && fmap.get(e.o)<=lomap.get(e.o))
+//   gw.goNext(e.o);
+//   return e;
+//   }
+//   }
+//   InEdgeIt Next(const InEdgeIt &e) {InEdgeIt t(e); return goNext(t);}
+// */
+//     //bool valid(const InEdgeIt e) { return gw.valid(e.i)||gw.valid(e.o);}
+
+//     //template<typename I> I &goNext(I &i); { return gw.goNext(i); }
+//     //template<typename I> I next(const I i); { return gw.goNext(i); }
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(Node v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return gw.head(e); }
+//     Node tail(const Edge& e) const { return gw.tail(e); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return gw.aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return gw.bNode(e); }
+  
+//     //template<typename I> bool valid(const I i);
+//     //{ return gw.valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return gw.setInvalid(i); }
+  
+//     Node addNode() { return gw.addNode(); }
+//     Edge addEdge(const Node& tail, const Node& head) { 
+//       return gw.addEdge(tail, head); }
+  
+//     template<typename I> void erase(const I& i) { gw.erase(i); }
+  
+//     void clear() { gw.clear(); }
+  
+//     template<typename S> class NodeMap : public Graph::NodeMap<S> { };
+//     template<typename S> class EdgeMap : public Graph::EdgeMap<S> { };
+  
+//     void setGraph(Graph& _graph) { graph = &_graph; }
+//     Graph& getGraph() { return (*graph); }
+
+//     //ResGraphWrapper() : graph(0) { }
+//     ResGraphWrapper(Graph& _graph) : graph(&_graph) { }
+//   };
+
+} //namespace hugo
+
+#endif //HUGO_GRAPH_WRAPPER_H
+

Added: hugo/trunk/src/work/marci/experiment/graph_wrapper_1.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/graph_wrapper_1.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,1832 @@
+// -*- c++ -*-
+#ifndef HUGO_GRAPH_WRAPPER_H
+#define HUGO_GRAPH_WRAPPER_H
+
+#include <invalid.h>
+
+namespace hugo {
+
+  template<typename Graph>
+  class TrivGraphWrapper {
+  protected:
+    Graph* graph;
+  
+  public:
+    typedef Graph BaseGraph;
+
+    typedef typename Graph::Node Node;
+    class NodeIt : public Graph::NodeIt { 
+    public:
+      NodeIt() { }
+      NodeIt(const typename Graph::NodeIt& n) : Graph::NodeIt(n) { }
+      NodeIt(const Invalid& i) : Graph::NodeIt(i) { }
+      NodeIt(const TrivGraphWrapper<Graph>& _G) : 
+	Graph::NodeIt(*(_G.graph)) { }
+    };
+    typedef typename Graph::Edge Edge;
+    //typedef typename Graph::OutEdgeIt OutEdgeIt;
+    class OutEdgeIt : public Graph::OutEdgeIt { 
+    public:
+      OutEdgeIt() { }
+      OutEdgeIt(const typename Graph::OutEdgeIt& e) : Graph::OutEdgeIt(e) { }
+      OutEdgeIt(const Invalid& i) : Graph::OutEdgeIt(i) { }
+      OutEdgeIt(const TrivGraphWrapper<Graph>& _G, const Node& n) : 
+	Graph::OutEdgeIt(*(_G.graph), n) { }
+    };
+    //typedef typename Graph::InEdgeIt InEdgeIt;
+    class InEdgeIt : public Graph::InEdgeIt { 
+    public:
+      InEdgeIt() { }
+      InEdgeIt(const typename Graph::InEdgeIt& e) : Graph::InEdgeIt(e) { }
+      InEdgeIt(const Invalid& i) : Graph::InEdgeIt(i) { }
+      InEdgeIt(const TrivGraphWrapper<Graph>& _G, const Node& n) : 
+	Graph::InEdgeIt(*(_G.graph), n) { }
+    };
+    //typedef typename Graph::SymEdgeIt SymEdgeIt;
+    //typedef typename Graph::EdgeIt EdgeIt;
+    class EdgeIt : public Graph::EdgeIt { 
+    public:
+      EdgeIt() { }
+      EdgeIt(const typename Graph::EdgeIt& e) : Graph::EdgeIt(e) { }
+      EdgeIt(const Invalid& i) : Graph::EdgeIt(i) { }
+      EdgeIt(const TrivGraphWrapper<Graph>& _G) : 
+	Graph::EdgeIt(*(_G.graph)) { }
+    };
+
+    //TrivGraphWrapper() : graph(0) { }
+    TrivGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//    void setGraph(Graph& _graph) { graph = &_graph; }
+//    Graph& getGraph() const { return (*graph); }
+
+    NodeIt& first(NodeIt& i) const { 
+      i=NodeIt(*this);
+      return i;
+    }
+    EdgeIt& first(EdgeIt& i) const { 
+      i=EdgeIt(*this);
+      return i;
+    }
+//     template<typename I> I& first(I& i) const { 
+//       //return graph->first(i); 
+//       i=I(*this);
+//       return i;
+//     }
+    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
+      i=OutEdgeIt(*this, p);
+      return i;
+    }
+    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
+      i=InEdgeIt(*this, p);
+      return i;
+    }
+//     template<typename I, typename P> I& first(I& i, const P& p) const { 
+//       //return graph->first(i, p);
+//       i=I(*this, p);
+//       return i;
+//     }
+    
+//    template<typename I> I getNext(const I& i) const { 
+//      return graph->getNext(i); }
+    template<typename I> I& next(I &i) const { graph->next(i); return i; }    
+
+    template< typename It > It first() const { 
+      It e; first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; first(e, v); return e; }
+
+    Node head(const Edge& e) const { return graph->head(e); }
+    Node tail(const Edge& e) const { return graph->tail(e); }
+
+    template<typename I> bool valid(const I& i) const 
+      { return graph->valid(i); }
+  
+    //template<typename I> void setInvalid(const I &i);
+    //{ return graph->setInvalid(i); }
+
+    int nodeNum() const { return graph->nodeNum(); }
+    int edgeNum() const { return graph->edgeNum(); }
+  
+    template<typename I> Node aNode(const I& e) const { 
+      return graph->aNode(e); }
+    template<typename I> Node bNode(const I& e) const { 
+      return graph->bNode(e); }
+  
+    Node addNode() const { return graph->addNode(); }
+    Edge addEdge(const Node& tail, const Node& head) const { 
+      return graph->addEdge(tail, head); }
+  
+    template<typename I> void erase(const I& i) const { graph->erase(i); }
+  
+    void clear() const { graph->clear(); }
+    
+    template<typename T> class NodeMap : public Graph::NodeMap<T> { 
+    public:
+      NodeMap(const TrivGraphWrapper<Graph>& _G) :  
+	Graph::NodeMap<T>(*(_G.graph)) { }
+      NodeMap(const TrivGraphWrapper<Graph>& _G, T a) : 
+	Graph::NodeMap<T>(*(_G.graph), a) { }
+    };
+
+    template<typename T> class EdgeMap : public Graph::EdgeMap<T> { 
+    public:
+      EdgeMap(const TrivGraphWrapper<Graph>& _G) :  
+	Graph::EdgeMap<T>(*(_G.graph)) { }
+      EdgeMap(const TrivGraphWrapper<Graph>& _G, T a) : 
+	Graph::EdgeMap<T>(*(_G.graph), a) { }
+    };
+
+    template<typename Map, typename T> class NodeMapWrapper {
+    protected:
+      Map* map;
+    public:
+      NodeMapWrapper(Map& _map) : map(&_map) { }
+      //template<typename T> 
+      void set(Node n, T a) { map->set(n, a); }
+      //template<typename T>
+      T get(Node n) const { return map->get(n); }
+    };
+
+    template<typename Map, typename T> class EdgeMapWrapper {
+    protected:
+      Map* map;
+    public:
+      EdgeMapWrapper(Map& _map) : map(&_map) { }
+      //template<typename T> 
+      void set(Edge n, T a) { map->set(n, a); }
+      //template<typename T>
+      T get(Edge n) const { return map->get(n); }
+    };
+  };
+
+  template<typename GraphWrapper>
+  class GraphWrapperSkeleton {
+  protected:
+    GraphWrapper gw;
+  
+  public:
+    //typedef typename GraphWrapper::BaseGraph BaseGraph;
+
+//     typedef typename GraphWrapper::Node Node;
+//     typedef typename GraphWrapper::NodeIt NodeIt;
+
+//     typedef typename GraphWrapper::Edge Edge;
+//     typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+//     typedef typename GraphWrapper::InEdgeIt InEdgeIt;
+//     //typedef typename GraphWrapper::SymEdgeIt SymEdgeIt;
+//     typedef typename GraphWrapper::EdgeIt EdgeIt;
+
+    typedef typename GraphWrapper::Node Node;
+    class NodeIt : public GraphWrapper::NodeIt { 
+    public:
+      NodeIt() { }
+      NodeIt(const typename GraphWrapper::NodeIt& n) : 
+	GraphWrapper::NodeIt(n) { }
+      NodeIt(const Invalid& i) : GraphWrapper::NodeIt(i) { }
+      NodeIt(const GraphWrapperSkeleton<GraphWrapper>& _G) : 
+	GraphWrapper::NodeIt(_G.gw) { }
+    };
+    typedef typename GraphWrapper::Edge Edge;
+    //typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    class OutEdgeIt : public GraphWrapper::OutEdgeIt { 
+    public:
+      OutEdgeIt() { }
+      OutEdgeIt(const typename GraphWrapper::OutEdgeIt& e) : 
+	GraphWrapper::OutEdgeIt(e) { }
+      OutEdgeIt(const Invalid& i) : GraphWrapper::OutEdgeIt(i) { }
+      OutEdgeIt(const GraphWrapperSkeleton<GraphWrapper>& _G, const Node& n) : 
+	GraphWrapper::OutEdgeIt(_G.gw, n) { }
+    };
+    //typedef typename GraphWrapper::InEdgeIt InEdgeIt;
+    class InEdgeIt : public GraphWrapper::InEdgeIt { 
+    public:
+      InEdgeIt() { }
+      InEdgeIt(const typename GraphWrapper::InEdgeIt& e) : 
+	GraphWrapper::InEdgeIt(e) { }
+      InEdgeIt(const Invalid& i) : GraphWrapper::InEdgeIt(i) { }
+      InEdgeIt(const GraphWrapperSkeleton<GraphWrapper>& _G, const Node& n) : 
+	GraphWrapper::InEdgeIt(_G.gw, n) { }
+    };
+    //typedef typename GraphWrapper::SymEdgeIt SymEdgeIt;
+    //typedef typename GraphWrapper::EdgeIt EdgeIt;
+    class EdgeIt : public GraphWrapper::EdgeIt { 
+    public:
+      EdgeIt() { }
+      EdgeIt(const typename GraphWrapper::EdgeIt& e) : 
+	GraphWrapper::EdgeIt(e) { }
+      EdgeIt(const Invalid& i) : GraphWrapper::EdgeIt(i) { }
+      EdgeIt(const GraphWrapperSkeleton<GraphWrapper>& _G) : 
+	GraphWrapper::EdgeIt(_G.gw) { }
+    };
+
+
+    //GraphWrapperSkeleton() : gw() { }
+    GraphWrapperSkeleton(GraphWrapper _gw) : gw(_gw) { }
+
+    //void setGraph(BaseGraph& _graph) { gw.setGraph(_graph); }
+    //BaseGraph& getGraph() const { return gw.getGraph(); }
+    
+    template<typename I> I& first(I& i) const {       
+      i=I(*this);
+      return i;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      i=I(*this, p);
+      return i; 
+    }
+    
+//    template<typename I> I getNext(const I& i) const { return gw.getNext(i); }
+    template<typename I> I& next(I &i) const { gw.next(i); return i; }    
+
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+
+    Node head(const Edge& e) const { return gw.head(e); }
+    Node tail(const Edge& e) const { return gw.tail(e); }
+
+    template<typename I> bool valid(const I& i) const { return gw.valid(i); }
+  
+    //template<typename I> void setInvalid(const I &i);
+    //{ return graph->setInvalid(i); }
+
+    int nodeNum() const { return gw.nodeNum(); }
+    int edgeNum() const { return gw.edgeNum(); }
+  
+    template<typename I> Node aNode(const I& e) const { return gw.aNode(e); }
+    template<typename I> Node bNode(const I& e) const { return gw.bNode(e); }
+  
+    Node addNode() const { return gw.addNode(); }
+    Edge addEdge(const Node& tail, const Node& head) const { 
+      return gw.addEdge(tail, head); }
+  
+    template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+    void clear() const { gw.clear(); }
+    
+    template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+    public:
+      NodeMap(const GraphWrapperSkeleton<GraphWrapper>& _G) :  
+	GraphWrapper::NodeMap<T>(_G.gw) { }
+      NodeMap(const GraphWrapperSkeleton<GraphWrapper>& _G, T a) : 
+	GraphWrapper::NodeMap<T>(_G.gw, a) { }
+    };
+
+    template<typename T> class EdgeMap : public GraphWrapper::EdgeMap<T> { 
+    public:
+      EdgeMap(const GraphWrapperSkeleton<GraphWrapper>& _G) :  
+	GraphWrapper::EdgeMap<T>(_G.gw) { }
+      EdgeMap(const GraphWrapperSkeleton<GraphWrapper>& _G, T a) : 
+	GraphWrapper::EdgeMap<T>(_G.gw, a) { }
+    };
+  };
+
+  template<typename GraphWrapper>
+  class GraphWrapperSkeleton1 {
+  protected:
+    GraphWrapper* g;
+  
+  public:
+    //typedef typename GraphWrapper::BaseGraph BaseGraph;
+
+//     typedef typename GraphWrapper::Node Node;
+//     typedef typename GraphWrapper::NodeIt NodeIt;
+
+//     typedef typename GraphWrapper::Edge Edge;
+//     typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+//     typedef typename GraphWrapper::InEdgeIt InEdgeIt;
+//     //typedef typename GraphWrapper::SymEdgeIt SymEdgeIt;
+//     typedef typename GraphWrapper::EdgeIt EdgeIt;
+
+    typedef typename GraphWrapper::Node Node;
+    class NodeIt : public GraphWrapper::NodeIt { 
+    public:
+      NodeIt() { }
+      NodeIt(const typename GraphWrapper::NodeIt& n) : 
+	GraphWrapper::NodeIt(n) { }
+      NodeIt(const Invalid& i) : GraphWrapper::NodeIt(i) { }
+      NodeIt(const GraphWrapperSkeleton1<GraphWrapper>& _G) : 
+	GraphWrapper::NodeIt(*(_G.g)) { }
+    };
+    typedef typename GraphWrapper::Edge Edge;
+    //typedef typename GraphWrapper::OutEdgeIt OutEdgeIt;
+    class OutEdgeIt : public GraphWrapper::OutEdgeIt { 
+    public:
+      OutEdgeIt() { }
+      OutEdgeIt(const typename GraphWrapper::OutEdgeIt& e) : 
+	GraphWrapper::OutEdgeIt(e) { }
+      OutEdgeIt(const Invalid& i) : GraphWrapper::OutEdgeIt(i) { }
+      OutEdgeIt(const GraphWrapperSkeleton1<GraphWrapper>& _G, const Node& n) : 
+	GraphWrapper::OutEdgeIt(*(_G.g), n) { }
+    };
+    //typedef typename GraphWrapper::InEdgeIt InEdgeIt;
+    class InEdgeIt : public GraphWrapper::InEdgeIt { 
+    public:
+      InEdgeIt() { }
+      InEdgeIt(const typename GraphWrapper::InEdgeIt& e) : 
+	GraphWrapper::InEdgeIt(e) { }
+      InEdgeIt(const Invalid& i) : GraphWrapper::InEdgeIt(i) { }
+      InEdgeIt(const GraphWrapperSkeleton1<GraphWrapper>& _G, const Node& n) : 
+	GraphWrapper::InEdgeIt(*(_G.g), n) { }
+    };
+    //typedef typename GraphWrapper::SymEdgeIt SymEdgeIt;
+    //typedef typename GraphWrapper::EdgeIt EdgeIt;
+    class EdgeIt : public GraphWrapper::EdgeIt { 
+    public:
+      EdgeIt() { }
+      EdgeIt(const typename GraphWrapper::EdgeIt& e) : 
+	GraphWrapper::EdgeIt(e) { }
+      EdgeIt(const Invalid& i) : GraphWrapper::EdgeIt(i) { }
+      EdgeIt(const GraphWrapperSkeleton1<GraphWrapper>& _G) : 
+	GraphWrapper::EdgeIt(*(_G.g)) { }
+    };
+
+
+    //GraphWrapperSkeleton() : gw() { }
+    GraphWrapperSkeleton1(GraphWrapper& _gw) : g(&_gw) { }
+
+    //void setGraph(BaseGraph& _graph) { gw.setGraph(_graph); }
+    //BaseGraph& getGraph() const { return gw.getGraph(); }
+    
+    template<typename I> I& first(I& i) const {       
+      i=I(*this);
+      return i;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      i=I(*this, p);
+      return i; 
+    }
+    
+//    template<typename I> I getNext(const I& i) const { return gw.getNext(i); }
+    template<typename I> I& next(I &i) const { g->next(i); return i; }    
+
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+
+    Node head(const Edge& e) const { return g->head(e); }
+    Node tail(const Edge& e) const { return g->tail(e); }
+
+    template<typename I> bool valid(const I& i) const { return g->valid(i); }
+  
+    //template<typename I> void setInvalid(const I &i);
+    //{ return graph->setInvalid(i); }
+
+    int nodeNum() const { return g->nodeNum(); }
+    int edgeNum() const { return g->edgeNum(); }
+  
+    template<typename I> Node aNode(const I& e) const { return g->aNode(e); }
+    template<typename I> Node bNode(const I& e) const { return g->bNode(e); }
+  
+    Node addNode() const { return g->addNode(); }
+    Edge addEdge(const Node& tail, const Node& head) const { 
+      return g->addEdge(tail, head); }
+  
+    template<typename I> void erase(const I& i) const { g->erase(i); }
+  
+    void clear() const { g->clear(); }
+    
+    template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+    public:
+      NodeMap(const GraphWrapperSkeleton1<GraphWrapper>& _G) :  
+	GraphWrapper::NodeMap<T>(*(_G.g)) { }
+      NodeMap(const GraphWrapperSkeleton1<GraphWrapper>& _G, T a) : 
+	GraphWrapper::NodeMap<T>(*(_G.g), a) { }
+    };
+
+    template<typename T> class EdgeMap : public GraphWrapper::EdgeMap<T> { 
+    public:
+      EdgeMap(const GraphWrapperSkeleton1<GraphWrapper>& _G) :  
+	GraphWrapper::EdgeMap<T>(*(_G.g)) { }
+      EdgeMap(const GraphWrapperSkeleton1<GraphWrapper>& _G, T a) : 
+	GraphWrapper::EdgeMap<T>(*(_G.g), a) { }
+    };
+  };
+
+
+//   template<typename Graph>
+//   class RevGraphWrapper
+//   {
+//   protected:
+//     Graph* graph;
+  
+//   public:
+//     typedef Graph BaseGraph;
+
+//     typedef typename Graph::Node Node;    
+//     typedef typename Graph::NodeIt NodeIt;
+  
+//     typedef typename Graph::Edge Edge;
+//     typedef typename Graph::OutEdgeIt InEdgeIt;
+//     typedef typename Graph::InEdgeIt OutEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename Graph::EdgeIt EdgeIt;
+
+//     //RevGraphWrapper() : graph(0) { }
+//     RevGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//     void setGraph(Graph& _graph) { graph = &_graph; }
+//     Graph& getGraph() const { return (*graph); }
+    
+//     template<typename I> I& first(I& i) const { return graph->first(i); }
+//     template<typename I, typename P> I& first(I& i, const P& p) const { 
+//       return graph->first(i, p); }
+
+//     template<typename I> I getNext(const I& i) const { 
+//       return graph->getNext(i); }
+//     template<typename I> I& next(I &i) const { return graph->next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return graph->tail(e); }
+//     Node tail(const Edge& e) const { return graph->head(e); }
+  
+//     template<typename I> bool valid(const I& i) const 
+//       { return graph->valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return graph->aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return graph->bNode(e); }
+
+//     Node addNode() const { return graph->addNode(); }
+//     Edge addEdge(const Node& tail, const Node& head) const { 
+//       return graph->addEdge(tail, head); }
+  
+//     int nodeNum() const { return graph->nodeNum(); }
+//     int edgeNum() const { return graph->edgeNum(); }
+  
+//     template<typename I> void erase(const I& i) const { graph->erase(i); }
+  
+//     void clear() const { graph->clear(); }
+
+//     template<typename T> class NodeMap : public Graph::NodeMap<T> { 
+//     public:
+//       NodeMap(const RevGraphWrapper<Graph>& _G) : 
+// 	Graph::NodeMap<T>(_G.getGraph()) { }
+//       NodeMap(const RevGraphWrapper<Graph>& _G, T a) : 
+// 	Graph::NodeMap<T>(_G.getGraph(), a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public Graph::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const RevGraphWrapper<Graph>& _G) : 
+// 	Graph::EdgeMap<T>(_G.getGraph()) { }
+//       EdgeMap(const RevGraphWrapper<Graph>& _G, T a) : 
+// 	Graph::EdgeMap<T>(_G.getGraph(), a) { }
+//     };
+//   };
+
+//   template<typename /*Graph*/GraphWrapper
+//   /*=typename GraphWrapperSkeleton< TrivGraphWrapper<Graph>*/ >
+//   class RevGraphWrapper : 
+//     public GraphWrapper/*GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/ {
+//   protected:
+//     //Graph* graph;
+    
+//   public:
+//     //typedef Graph BaseGraph;
+
+//     //typedef typename Graph::Node Node;    
+//     //typedef typename Graph::NodeIt NodeIt;
+  
+//     //typedef typename Graph::Edge Edge;
+//     typedef typename GraphWrapper/*typename GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/::OutEdgeIt InEdgeIt;
+//     typedef typename GraphWrapper/*typename GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/::InEdgeIt OutEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename Graph::EdgeIt EdgeIt;
+
+//     //RevGraphWrapper() : graph(0) { }
+//     RevGraphWrapper(GraphWrapper _gw/*BaseGraph& _graph*/) : GraphWrapper/*GraphWrapperSkeleton< TrivGraphWrapper<Graph> >*/(_gw/*TrivGraphWrapper<Graph>(_graph)*/) { }
+    
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+    
+//     //template<typename I> I& first(I& i) const { return graph->first(i); }
+//     //template<typename I, typename P> I& first(I& i, const P& p) const { 
+//     //  return graph->first(i, p); }
+
+//     //template<typename I> I getNext(const I& i) const { 
+//     //  return graph->getNext(i); }
+//     //template<typename I> I& next(I &i) const { return graph->next(i); }    
+
+//     //template< typename It > It first() const { 
+//     //  It e; first(e); return e; }
+
+//     //template< typename It > It first(const Node& v) const { 
+//     //  It e; first(e, v); return e; }
+
+//     //Node head(const Edge& e) const { return graph->tail(e); }
+//     //Node tail(const Edge& e) const { return graph->head(e); }
+  
+//     //template<typename I> bool valid(const I& i) const 
+//     //  { return graph->valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+  
+//     //template<typename I> Node aNode(const I& e) const { 
+//     //  return graph->aNode(e); }
+//     //template<typename I> Node bNode(const I& e) const { 
+//     //  return graph->bNode(e); }
+
+//     //Node addNode() const { return graph->addNode(); }
+//     //Edge addEdge(const Node& tail, const Node& head) const { 
+//     //  return graph->addEdge(tail, head); }
+  
+//     //int nodeNum() const { return graph->nodeNum(); }
+//     //int edgeNum() const { return graph->edgeNum(); }
+  
+//     //template<typename I> void erase(const I& i) const { graph->erase(i); }
+  
+//     //void clear() const { graph->clear(); }
+
+//     template<typename T> class NodeMap : 
+//       public GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::NodeMap<T> 
+//     { 
+//     public:
+//       NodeMap(const RevGraphWrapper<GraphWrapper>& _gw) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::NodeMap<T>(_gw) { }
+//       NodeMap(const RevGraphWrapper<GraphWrapper>& _gw, T a) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::NodeMap<T>(_gw, a) { }
+//     };
+    
+//     template<typename T> class EdgeMap : 
+//       public GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const RevGraphWrapper<GraphWrapper>& _gw) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::EdgeMap<T>(_gw) { }
+//       EdgeMap(const RevGraphWrapper<GraphWrapper>& _gw, T a) : 
+// 	GraphWrapper/*Skeleton< TrivGraphWrapper<Graph> >*/::EdgeMap<T>(_gw, a) { }
+//     };
+//   };
+
+  template<typename GraphWrapper>
+  class RevGraphWrapper : public GraphWrapperSkeleton1<GraphWrapper> {
+  public:
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Edge Edge;
+    //FIXME 
+    //If GraphWrapper::OutEdgeIt is not defined
+    //and we do not want to use RevGraphWrapper::InEdgeIt,
+    //this won't work, because of typedef
+    //OR
+    //graphs have to define their non-existing iterators to void
+    //Unfortunately all the typedefs are instantiated in templates, 
+    //unlike other stuff
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::OutEdgeIt InEdgeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::InEdgeIt OutEdgeIt;
+
+    RevGraphWrapper(GraphWrapper& _gw) : 
+      GraphWrapperSkeleton1<GraphWrapper>(_gw) { }  
+
+    Node head(const Edge& e) const 
+      { return GraphWrapperSkeleton1<GraphWrapper>::tail(e); }
+    Node tail(const Edge& e) const 
+      { return GraphWrapperSkeleton1<GraphWrapper>::head(e); }
+  };
+
+  //Subgraph on the same node-set and partial edge-set
+  template<typename GraphWrapper, typename EdgeFilterMap>
+  class SubGraphWrapper : public GraphWrapperSkeleton1<GraphWrapper> {
+  protected:
+    EdgeFilterMap* filter_map;
+  public:
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::NodeIt NodeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Edge Edge;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::EdgeIt EdgeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::InEdgeIt InEdgeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::OutEdgeIt OutEdgeIt;
+
+    SubGraphWrapper(GraphWrapper& _gw, EdgeFilterMap& _filter_map) : 
+      GraphWrapperSkeleton1<GraphWrapper>(_gw), filter_map(&_filter_map) { }  
+
+    template<typename I> I& first(I& i) const { 
+      g->first(i); 
+      while (g->valid(i) && !filter_map->get(i)) { g->next(i); }
+      return i;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      g->first(i, p); 
+      while (g->valid(i) && !filter_map->get(i)) { g->next(i); }
+      return i;
+    }
+    
+    //template<typename I> I getNext(const I& i) const { 
+    //  return gw.getNext(i); 
+    //}
+    template<typename I> I& next(I &i) const { 
+      g->next(i); 
+      while (g->valid(i) && !filter_map->get(i)) { g->next(i); }
+      return i;
+    }
+    
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+    
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+  };
+
+//   template<typename GraphWrapper>
+//   class UndirGraphWrapper {
+//   protected:
+//     //Graph* graph;
+//     GraphWrapper gw;
+
+//   public:
+//     typedef GraphWrapper BaseGraph;
+
+//     typedef typename GraphWrapper::Node Node;
+//     typedef typename GraphWrapper::NodeIt NodeIt;
+
+//     //typedef typename Graph::Edge Edge;
+//     //typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     //typedef typename Graph::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename Graph::EdgeIt EdgeIt;
+
+//     //private:
+//     typedef typename GraphWrapper::Edge GraphEdge;
+//     typedef typename GraphWrapper::OutEdgeIt GraphOutEdgeIt;
+//     typedef typename GraphWrapper::InEdgeIt GraphInEdgeIt;
+//     //public:
+
+//     //UndirGraphWrapper() : graph(0) { }
+//     UndirGraphWrapper(GraphWrapper _gw) : gw(_gw) { }
+
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+  
+//     class Edge {
+//       friend class UndirGraphWrapper<GraphWrapper>;
+//       bool out_or_in; //true iff out
+//       GraphOutEdgeIt out;
+//       GraphInEdgeIt in;
+//     public:
+//       Edge() : out_or_in(), out(), in() { }
+//       Edge(const Invalid& i) : out_or_in(false), out(), in(i) { }
+//       operator GraphEdge() const {
+// 	if (out_or_in) return(out); else return(in);
+//       }
+//       friend bool operator==(const Edge& u, const Edge& v) { 
+// 	if (v.out_or_in) 
+// 	  return (u.out_or_in && u.out==v.out);
+// 	else
+// 	  return (!u.out_or_in && u.in==v.in);
+//       } 
+//       friend bool operator!=(const Edge& u, const Edge& v) { 
+// 	if (v.out_or_in) 
+// 	  return (!u.out_or_in || u.out!=v.out);
+// 	else
+// 	  return (u.out_or_in || u.in!=v.in);
+//       } 
+//     };
+
+//     class OutEdgeIt : public Edge {
+//       friend class UndirGraphWrapper<GraphWrapper>;
+//     public:
+//       OutEdgeIt() : Edge() { }
+//       OutEdgeIt(const Invalid& i) : Edge(i) { }
+//       OutEdgeIt(const UndirGraphWrapper<GraphWrapper>& _G, const Node& n) 
+// 	: Edge() { 
+// 	out_or_in=true;
+// 	_G.gw.first(out, n);
+// 	if (!(_G.gw.valid(out))) {
+// 	  out_or_in=false;
+// 	  _G.gw.first(in, n);
+// 	}
+//       }
+//     };
+
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+//       e.out_or_in=true;
+//       gw.first(e.out, n);
+//       if (!(gw.valid(e.out))) {
+// 	e.out_or_in=false;
+// 	gw.first(e.in, n);
+//       }
+//       return e;
+//     }
+
+//     OutEdgeIt& next(OutEdgeIt& e) const {
+//       if (e.out_or_in) {
+// 	Node n=gw.tail(e.out);
+// 	gw.next(e.out);
+// 	if (!gw.valid(e.out)) {
+// 	  e.out_or_in=false;
+// 	  gw.first(e.in, n);
+// 	}
+//       } else {
+// 	gw.next(e.in);
+//       }
+//       return e;
+//     }
+
+//     Node aNode(const OutEdgeIt& e) const { 
+//       if (e.out_or_in) return gw.tail(e); else return gw.head(e); }
+//     Node bNode(const OutEdgeIt& e) const { 
+//       if (e.out_or_in) return gw.head(e); else return gw.tail(e); }
+
+//     typedef OutEdgeIt InEdgeIt; 
+
+//     template<typename I> I& first(I& i) const { return gw.first(i); }
+// //     template<typename I, typename P> I& first(I& i, const P& p) const { 
+// //       return graph->first(i, p); }
+    
+//     template<typename I> I getNext(const I& i) const { 
+//       return gw.getNext(i); }
+//     template<typename I> I& next(I &i) const { return gw.next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return gw.head(e); }
+//     Node tail(const Edge& e) const { return gw.tail(e); }
+
+//     template<typename I> bool valid(const I& i) const 
+//       { return gw.valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+
+//     int nodeNum() const { return gw.nodeNum(); }
+//     int edgeNum() const { return gw.edgeNum(); }
+  
+// //     template<typename I> Node aNode(const I& e) const { 
+// //       return graph->aNode(e); }
+// //     template<typename I> Node bNode(const I& e) const { 
+// //       return graph->bNode(e); }
+  
+//     Node addNode() const { return gw.addNode(); }
+// // FIXME: ez igy nem jo, mert nem
+// //    Edge addEdge(const Node& tail, const Node& head) const { 
+// //      return graph->addEdge(tail, head); }
+  
+//     template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//     void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+//     public:
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw) { }
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public GraphWrapper::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapper::EdgeMap<T>(_G.gw) { }
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::EdgeMap<T>(_G.gw, a) { }
+//     };
+//   };
+
+
+  template<typename GraphWrapper>
+  class UndirGraphWrapper : public GraphWrapperSkeleton1<GraphWrapper> {
+  protected:
+//    GraphWrapper gw;
+
+  public:
+    //typedef GraphWrapper BaseGraph;
+
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::NodeIt NodeIt;
+
+    //private:
+    //FIXME ezeknek valojaban a GraphWrapper megfelelo dolgai kellene hogy 
+    //legyenek, at kell irni
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/
+    GraphWrapper::Edge GraphEdge;
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/ 
+    GraphWrapper::OutEdgeIt GraphOutEdgeIt;
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/ 
+    GraphWrapper::InEdgeIt GraphInEdgeIt;
+    //public:
+
+    //UndirGraphWrapper() : graph(0) { }
+    UndirGraphWrapper(GraphWrapper& _gw) : 
+      GraphWrapperSkeleton1<GraphWrapper>(_gw) { }  
+
+    //UndirGraphWrapper(GraphWrapper _gw) : gw(_gw) { }
+
+    //void setGraph(Graph& _graph) { graph = &_graph; }
+    //Graph& getGraph() const { return (*graph); }
+  
+    class Edge {
+      friend class UndirGraphWrapper<GraphWrapper>;
+    protected:
+      bool out_or_in; //true iff out
+      GraphOutEdgeIt out;
+      GraphInEdgeIt in;
+    public:
+      Edge() : out_or_in(), out(), in() { }
+      Edge(const Invalid& i) : out_or_in(false), out(), in(i) { }
+      operator GraphEdge() const {
+	if (out_or_in) return(out); else return(in);
+      }
+//FIXME
+//2 edges are equal if they "refer" to the same physical edge 
+//is it good?
+      friend bool operator==(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  if (u.out_or_in) return (u.out==v.out); else return (u.out==v.in);
+	//return (u.out_or_in && u.out==v.out);
+	else
+	  if (u.out_or_in) return (u.out==v.in); else return (u.in==v.in);
+	//return (!u.out_or_in && u.in==v.in);
+      } 
+      friend bool operator!=(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  if (u.out_or_in) return (u.out!=v.out); else return (u.out!=v.in);
+	//return (!u.out_or_in || u.out!=v.out);
+	else
+	  if (u.out_or_in) return (u.out!=v.in); else return (u.in!=v.in);
+	//return (u.out_or_in || u.in!=v.in);
+      } 
+    };
+
+    class OutEdgeIt : public Edge {
+      friend class UndirGraphWrapper<GraphWrapper>;
+    public:
+      OutEdgeIt() : Edge() { }
+      OutEdgeIt(const Invalid& i) : Edge(i) { }
+      OutEdgeIt(const UndirGraphWrapper<GraphWrapper>& _G, const Node& n) 
+	: Edge() { 
+	out_or_in=true; _G.g->first(out, n);
+	if (!(_G.g->valid(out))) { out_or_in=false; _G.g->first(in, n);	}
+      }
+    };
+
+    typedef OutEdgeIt InEdgeIt; 
+
+    class EdgeIt : public Edge {
+      friend class UndirGraphWrapper<GraphWrapper>;
+    protected:
+      NodeIt v;
+    public:
+      EdgeIt() : Edge() { }
+      EdgeIt(const Invalid& i) : Edge(i) { }
+      EdgeIt(const UndirGraphWrapper<GraphWrapper>& _G) 
+	: Edge() { 
+	out_or_in=true;
+	//Node v;
+	_G.first(v);
+	if (_G.valid(v)) _G.g->first(out); else out=INVALID;
+	while (_G.valid(v) && !_G.g->valid(out)) { 
+	  _G.g->next(v); 
+	  if (_G.valid(v)) _G.g->first(out); 
+	}
+      }
+    };
+
+    OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+      e.out_or_in=true; g->first(e.out, n);
+      if (!(g->valid(e.out))) { e.out_or_in=false; g->first(e.in, n); }
+      return e;
+    }
+
+    EdgeIt& first(EdgeIt& e) const {
+      e.out_or_in=true;
+      //NodeIt v;
+      first(e.v);
+      if (valid(e.v)) g->first(e.out, e.v); else e.out=INVALID;
+      while (valid(e.v) && !g->valid(e.out)) { 
+	g->next(e.v); 
+	if (valid(e.v)) g->first(e.out, e.v); 
+      }
+      return e;
+    }
+
+    template<typename I> I& first(I& i) const { g->first(i); return i; }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      g->first(i, p); return i; }
+
+    OutEdgeIt& next(OutEdgeIt& e) const {
+      if (e.out_or_in) {
+	Node n=g->tail(e.out);
+	g->next(e.out);
+	if (!g->valid(e.out)) { e.out_or_in=false; g->first(e.in, n); }
+      } else {
+	g->next(e.in);
+      }
+      return e;
+    }
+
+    EdgeIt& next(EdgeIt& e) const {
+      //NodeIt v=tail(e);
+      g->next(e.out);
+      while (valid(e.v) && !g->valid(e.out)) { 
+	next(e.v); 
+	if (valid(e.v)) g->first(e.out, e.v); 
+      }
+      return e;
+    }
+
+    template<typename I> I& next(I &i) const { return g->next(i); }    
+//    template<typename I> I getNext(const I& i) const { return gw.getNext(i); }
+
+    template< typename It > It first() const { 
+      It e; first(e); return e; }
+
+    template< typename It > It first(const Node& v) const { 
+      It e; first(e, v); return e; }
+
+//    Node head(const Edge& e) const { return gw.head(e); }
+//    Node tail(const Edge& e) const { return gw.tail(e); }
+
+//    template<typename I> bool valid(const I& i) const 
+//      { return gw.valid(i); }
+  
+//    int nodeNum() const { return gw.nodeNum(); }
+//    int edgeNum() const { return gw.edgeNum(); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return graph->aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return graph->bNode(e); }
+
+    Node aNode(const OutEdgeIt& e) const { 
+      if (e.out_or_in) return g->tail(e); else return g->head(e); }
+    Node bNode(const OutEdgeIt& e) const { 
+      if (e.out_or_in) return g->head(e); else return g->tail(e); }
+  
+//    Node addNode() const { return gw.addNode(); }
+
+// FIXME: ez igy nem jo, mert nem
+//    Edge addEdge(const Node& tail, const Node& head) const { 
+//      return graph->addEdge(tail, head); }
+  
+//    template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//    void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+//     public:
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw) { }
+//       NodeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::NodeMap<T>(_G.gw, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : 
+//       public GraphWrapperSkeleton<GraphWrapper>::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G) : 
+// 	GraphWrapperSkeleton<GraphWrapper>::EdgeMap<T>(_G.gw) { }
+//       EdgeMap(const UndirGraphWrapper<GraphWrapper>& _G, T a) : 
+// 	GraphWrapper::EdgeMap<T>(_G.gw, a) { }
+//     };
+   };
+
+
+
+
+
+//   template<typename Graph>
+//   class SymGraphWrapper
+//   {
+//     Graph* graph;
+  
+//   public:
+//     typedef Graph BaseGraph;
+
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+  
+//     typedef typename Graph::NodeIt NodeIt;
+    
+//     //FIXME tag-ekkel megcsinalni, hogy abbol csinaljon
+//     //iranyitatlant, ami van
+//     //mert csak 1 dolgot lehet be typedef-elni
+//     typedef typename Graph::OutEdgeIt SymEdgeIt;
+//     //typedef typename Graph::InEdgeIt SymEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename Graph::EdgeIt EdgeIt;
+
+//     int nodeNum() const { return graph->nodeNum(); }
+//     int edgeNum() const { return graph->edgeNum(); }
+    
+//     template<typename I> I& first(I& i) const { return graph->first(i); }
+//     template<typename I, typename P> I& first(I& i, const P& p) const { 
+//       return graph->first(i, p); }
+//     //template<typename I> I next(const I i); { return graph->goNext(i); }
+//     //template<typename I> I &goNext(I &i); { return graph->goNext(i); }
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(Node v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return graph->head(e); }
+//     Node tail(const Edge& e) const { return graph->tail(e); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return graph->aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return graph->bNode(e); }
+  
+//     //template<typename I> bool valid(const I i);
+//     //{ return graph->valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return graph->setInvalid(i); }
+  
+//     Node addNode() { return graph->addNode(); }
+//     Edge addEdge(const Node& tail, const Node& head) { 
+//       return graph->addEdge(tail, head); }
+  
+//     template<typename I> void erase(const I& i) { graph->erase(i); }
+  
+//     void clear() { graph->clear(); }
+  
+//     template<typename T> class NodeMap : public Graph::NodeMap<T> { };
+//     template<typename T> class EdgeMap : public Graph::EdgeMap<T> { };
+  
+//     void setGraph(Graph& _graph) { graph = &_graph; }
+//     Graph& getGraph() { return (*graph); }
+
+//     //SymGraphWrapper() : graph(0) { }
+//     SymGraphWrapper(Graph& _graph) : graph(&_graph) { }
+//   };
+
+
+  template<typename GraphWrapper, typename Number, typename FlowMap, typename CapacityMap>
+  class ResGraphWrapper : public GraphWrapperSkeleton1<GraphWrapper>{
+  public:
+    //typedef Graph BaseGraph;
+    //typedef TrivGraphWrapper<const Graph> GraphWrapper;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::NodeIt NodeIt;
+  private:
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/
+    GraphWrapper::OutEdgeIt OldOutEdgeIt;
+    typedef typename /*GraphWrapperSkeleton<GraphWrapper>*/
+    GraphWrapper::InEdgeIt OldInEdgeIt;
+  protected:
+    //const Graph* graph;
+    //GraphWrapper gw;
+    FlowMap* flow;
+    const CapacityMap* capacity;
+  public:
+
+    ResGraphWrapper(GraphWrapper& _gw, FlowMap& _flow, 
+		    const CapacityMap& _capacity) : 
+      GraphWrapperSkeleton1<GraphWrapper>(_gw), 
+      flow(&_flow), capacity(&_capacity) { }
+
+    //void setGraph(const Graph& _graph) { graph = &_graph; }
+    //const Graph& getGraph() const { return (*graph); }
+
+    class Edge; 
+    class OutEdgeIt; 
+    friend class Edge; 
+    friend class OutEdgeIt; 
+
+    class Edge {
+      friend class ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>;
+    protected:
+      bool out_or_in; //true, iff out
+      OldOutEdgeIt out;
+      OldInEdgeIt in;
+    public:
+      Edge() : out_or_in(true) { } 
+      Edge(const Invalid& i) : out_or_in(false), out(), in(i) { }
+//       bool valid() const { 
+// 	return out_or_in && out.valid() || in.valid(); }
+      friend bool operator==(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  return (u.out_or_in && u.out==v.out);
+	else
+	  return (!u.out_or_in && u.in==v.in);
+      } 
+      friend bool operator!=(const Edge& u, const Edge& v) { 
+	if (v.out_or_in) 
+	  return (!u.out_or_in || u.out!=v.out);
+	else
+	  return (u.out_or_in || u.in!=v.in);
+      } 
+    };
+
+
+    class OutEdgeIt : public Edge {
+      friend class ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>;
+    public:
+      OutEdgeIt() { }
+      //FIXME
+      OutEdgeIt(const Edge& e) : Edge(e) { }
+      OutEdgeIt(const Invalid& i) : Edge(i) { }
+    protected:
+      OutEdgeIt(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& resG, Node v) : Edge() { 
+	resG.g->first(out, v);
+	while( resG.g->valid(out) && !(resG.resCap(out)>0) ) { resG.g->next(out); }
+	if (!resG.g->valid(out)) {
+	  out_or_in=0;
+	  resG.g->first(in, v);
+	  while( resG.g->valid(in) && !(resG.resCap(in)>0) ) { resG.g->next(in); }
+	}
+      }
+//     public:
+//       OutEdgeIt& operator++() { 
+// 	if (out_or_in) {
+// 	  Node v=/*resG->*/G->aNode(out);
+// 	  ++out;
+// 	  while( out.valid() && !(Edge::resCap()>0) ) { ++out; }
+// 	  if (!out.valid()) {
+// 	    out_or_in=0;
+// 	    G->first(in, v); 
+// 	    while( in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	  }
+// 	} else {
+// 	  ++in;
+// 	  while( in.valid() && !(Edge::resCap()>0) ) { ++in; } 
+// 	}
+// 	return *this; 
+//       }
+    };
+
+    //FIXME This is just for having InEdgeIt
+    typedef void InEdgeIt;
+
+    class EdgeIt : public Edge {
+      friend class ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>;
+      NodeIt v; 
+    public:
+      EdgeIt() { }
+      //EdgeIt(const EdgeIt& e) : Edge(e), v(e.v) { }
+      EdgeIt(const Invalid& i) : Edge(i) { }
+      EdgeIt(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& resG) : Edge() { 
+	resG.g->first(v);
+	if (resG.g->valid(v)) resG.g->first(out, v); else out=INVALID;
+	while (resG.g->valid(out) && !(resG.resCap(out)>0) ) { resG.g->next(out); }
+	while (resG.g->valid(v) && !resG.g->valid(out)) { 
+	  resG.g->next(v); 
+	  if (resG.g->valid(v)) resG.g->first(out, v); 
+	  while (resG.g->valid(out) && !(resG.resCap(out)>0) ) { resG.g->next(out); }
+	}
+	if (!resG.g->valid(out)) {
+	  out_or_in=0;
+	  resG.g->first(v);
+	  if (resG.g->valid(v)) resG.g->first(in, v); else in=INVALID;
+	  while (resG.g->valid(in) && !(resG.resCap(in)>0) ) { resG.g->next(in); }
+	  while (resG.g->valid(v) && !resG.g->valid(in)) { 
+	    resG.g->next(v); 
+	    if (resG.g->valid(v)) resG.g->first(in, v); 
+	    while (resG.g->valid(in) && !(resG.resCap(in)>0) ) { resG.g->next(in); }
+	  }
+	}
+      }
+//       EdgeIt& operator++() { 
+// 	if (out_or_in) {
+// 	  ++out;
+// 	  while (out.valid() && !(Edge::resCap()>0) ) { ++out; }
+// 	  while (v.valid() && !out.valid()) { 
+// 	    ++v; 
+// 	    if (v.valid()) G->first(out, v); 
+// 	    while (out.valid() && !(Edge::resCap()>0) ) { ++out; }
+// 	  }
+// 	  if (!out.valid()) {
+// 	    out_or_in=0;
+// 	    G->first(v);
+// 	    if (v.valid()) G->first(in, v); else in=OldInEdgeIt();
+// 	    while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	    while (v.valid() && !in.valid()) { 
+// 	      ++v; 
+// 	      if (v.valid()) G->first(in, v); 
+// 	      while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	    }  
+// 	  }
+// 	} else {
+// 	  ++in;
+// 	  while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	  while (v.valid() && !in.valid()) { 
+// 	    ++v; 
+// 	    if (v.valid()) G->first(in, v); 
+// 	    while (in.valid() && !(Edge::resCap()>0) ) { ++in; }
+// 	  }
+// 	}
+// 	return *this;
+//       }
+    };
+
+    NodeIt& first(NodeIt& v) const { g->first(v); return v; }
+    OutEdgeIt& first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); 
+      return e;
+    }
+    EdgeIt& first(EdgeIt& e) const { 
+      e=EdgeIt(*this); 
+      return e;
+    }
+   
+    NodeIt& next(NodeIt& n) const { return g->next(n); }
+
+    OutEdgeIt& next(OutEdgeIt& e) const { 
+      if (e.out_or_in) {
+	Node v=g->aNode(e.out);
+	g->next(e.out);
+	while( g->valid(e.out) && !(resCap(e.out)>0) ) { g->next(e.out); }
+	if (!g->valid(e.out)) {
+	  e.out_or_in=0;
+	  g->first(e.in, v); 
+	  while( g->valid(e.in) && !(resCap(e.in)>0) ) { g->next(e.in); }
+	}
+      } else {
+	g->next(e.in);
+	while( g->valid(e.in) && !(resCap(e.in)>0) ) { g->next(e.in); } 
+      }
+      return e;
+    }
+
+    EdgeIt& next(EdgeIt& e) const { 
+      if (e.out_or_in) {
+	g->next(e.out);
+	while (g->valid(e.out) && !(resCap(e.out)>0) ) { g->next(e.out); }
+	  while (g->valid(e.v) && !g->valid(e.out)) { 
+	    g->next(e.v); 
+	    if (g->valid(e.v)) g->first(e.out, e.v); 
+	    while (g->valid(e.out) && !(resCap(e.out)>0) ) { g->next(e.out); }
+	  }
+	  if (!g->valid(e.out)) {
+	    e.out_or_in=0;
+	    g->first(e.v);
+	    if (g->valid(e.v)) g->first(e.in, e.v); else e.in=INVALID;
+	    while (g->valid(e.in) && !(resCap(e.in)>0) ) { g->next(e.in); }
+	    while (g->valid(e.v) && !g->valid(e.in)) { 
+	      g->next(e.v); 
+	      if (g->valid(e.v)) g->first(e.in, e.v); 
+	      while (g->valid(e.in) && !(resCap(e.in)>0) ) { g->next(e.in); }
+	    }  
+	  }
+	} else {
+	  g->next(e.in);
+	  while (g->valid(e.in) && !(resCap(e.in)>0) ) { g->next(e.in); }
+	  while (g->valid(e.v) && !g->valid(e.in)) { 
+	    g->next(e.v); 
+	    if (g->valid(e.v)) g->first(e.in, e.v); 
+	    while (g->valid(e.in) && !(resCap(e.in)>0) ) { g->next(e.in); }
+	  }
+	}
+	return e;
+      }
+    
+
+    template< typename It >
+    It first() const { 
+      It e;
+      first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      first(e, v);
+      return e; 
+    }
+
+    Node tail(Edge e) const { 
+      return ((e.out_or_in) ? g->aNode(e.out) : g->aNode(e.in)); }
+    Node head(Edge e) const { 
+      return ((e.out_or_in) ? g->bNode(e.out) : g->bNode(e.in)); }
+
+    Node aNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? g->aNode(e.out) : g->aNode(e.in)); }
+    Node bNode(OutEdgeIt e) const { 
+      return ((e.out_or_in) ? g->bNode(e.out) : g->bNode(e.in)); }
+
+    int nodeNum() const { return g->nodeNum(); }
+    //FIXME
+    //int edgeNum() const { return g->edgeNum(); }
+
+
+    int id(Node v) const { return g->id(v); }
+
+    bool valid(Node n) const { return g->valid(n); }
+    bool valid(Edge e) const { 
+      return e.out_or_in ? g->valid(e.out) : g->valid(e.in); }
+
+    void augment(const Edge& e, Number a) const {
+      if (e.out_or_in)  
+	flow->set(e.out, flow->get(e.out)+a);
+      else  
+	flow->set(e.in, flow->get(e.in)-a);
+    }
+
+    Number resCap(const Edge& e) const { 
+      if (e.out_or_in) 
+	return (capacity->get(e.out)-flow->get(e.out)); 
+      else 
+	return (flow->get(e.in)); 
+    }
+
+    Number resCap(OldOutEdgeIt out) const { 
+      return (capacity->get(out)-flow->get(out)); 
+    }
+    
+    Number resCap(OldInEdgeIt in) const { 
+      return (flow->get(in)); 
+    }
+
+//     template<typename T> class NodeMap : public GraphWrapper::NodeMap<T> { 
+//     public:
+//       NodeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G) 
+// 	: GraphWrapper::NodeMap<T>(_G.gw) { }
+//       NodeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G, 
+// 	      T a) : GraphWrapper::NodeMap<T>(_G.gw, a) { }
+//     };
+
+//     template <typename T>
+//     class NodeMap {
+//       typename Graph::NodeMap<T> node_map; 
+//     public:
+//       NodeMap(const ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G) : node_map(*(_G.graph)) { }
+//       NodeMap(const ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G, T a) : node_map(*(_G.graph), a) { }
+//       void set(Node nit, T a) { node_map.set(nit, a); }
+//       T get(Node nit) const { return node_map.get(nit); }
+//     };
+
+    template <typename T>
+    class EdgeMap {
+      typename GraphWrapper::EdgeMap<T> forward_map, backward_map; 
+    public:
+      EdgeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G) : forward_map(_G.gw), backward_map(_G.gw) { }
+      EdgeMap(const ResGraphWrapper<GraphWrapper, Number, FlowMap, CapacityMap>& _G, T a) : forward_map(_G.gw, a), backward_map(_G.gw, a) { }
+      void set(Edge e, T a) { 
+	if (e.out_or_in) 
+	  forward_map.set(e.out, a); 
+	else 
+	  backward_map.set(e.in, a); 
+      }
+      T get(Edge e) { 
+	if (e.out_or_in) 
+	  return forward_map.get(e.out); 
+	else 
+	  return backward_map.get(e.in); 
+      }
+    };
+  };
+
+  //Subgraph on the same node-set and partial edge-set
+  template<typename GraphWrapper, typename FirstOutEdgesMap>
+  class ErasingFirstGraphWrapper : public GraphWrapperSkeleton1<GraphWrapper> {
+  protected:
+    FirstOutEdgesMap* first_out_edges;
+  public:
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Node Node;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::NodeIt NodeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::Edge Edge;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::EdgeIt EdgeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::InEdgeIt InEdgeIt;
+    typedef typename GraphWrapperSkeleton1<GraphWrapper>::OutEdgeIt OutEdgeIt;
+
+    ErasingFirstGraphWrapper(GraphWrapper& _gw, FirstOutEdgesMap& _first_out_edges) : 
+      GraphWrapperSkeleton1<GraphWrapper>(_gw), first_out_edges(&_first_out_edges) { }  
+
+    template<typename I> I& first(I& i) const { 
+      g->first(i); 
+      //while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+      e=first_out_edges->get(n);
+      return e;
+    }
+    template<typename I, typename P> I& first(I& i, const P& p) const { 
+      g->first(i, p); 
+      //while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    
+    //template<typename I> I getNext(const I& i) const { 
+    //  return gw.getNext(i); 
+    //}
+    template<typename I> I& next(I &i) const { 
+      g->next(i); 
+      //while (gw.valid(i) && !filter_map->get(i)) { gw.next(i); }
+      return i;
+    }
+    
+    template< typename It > It first() const { 
+      It e; this->first(e); return e; }
+    
+    template< typename It > It first(const Node& v) const { 
+      It e; this->first(e, v); return e; }
+
+    void erase(const OutEdgeIt& e) const {
+      OutEdgeIt f=e;
+      this->next(f);
+      first_out_edges->set(this->tail(e), f);
+    }
+  };
+
+//   template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+//   class ErasingResGraphWrapper : public ResGraphWrapper<Graph, Number, FlowMap, CapacityMap> {
+//   protected:
+//     ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt> first_out_edges;
+//     //ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<int> dist;
+//   public:
+//     ErasingResGraphWrapper(const Graph& _G, FlowMap& _flow, 
+// 			   const CapacityMap& _capacity) : 
+//       ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>(_G, _flow, _capacity), 
+//       first_out_edges(*this) /*, dist(*this)*/ { 
+//       for(NodeIt n=this->template first<NodeIt>(); this->valid(n); this->next(n)) {
+// 	OutEdgeIt e;
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(e, n);
+// 	first_out_edges.set(n, e);
+//       }
+//     }
+
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+  
+//     //TrivGraphWrapper() : graph(0) { }
+//     //ErasingResGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//     //typedef Graph BaseGraph;
+
+//     //typedef typename Graph::Node Node;
+//     //typedef typename Graph::NodeIt NodeIt;
+
+//     //typedef typename Graph::Edge Edge;
+//     //typedef typename Graph::OutEdgeIt OutEdgeIt;
+//     //typedef typename Graph::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename Graph::EdgeIt EdgeIt;
+
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Node Node;
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeIt NodeIt;
+
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Edge Edge;
+//     typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt OutEdgeIt;
+//     //typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     //typedef typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeIt EdgeIt;
+
+//     NodeIt& first(NodeIt& n) const { 
+//       return ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(n);
+//     }
+
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const { 
+//       e=first_out_edges.get(n);
+//       return e;
+//     }
+    
+//     //ROSSZ template<typename I> I& first(I& i) const { return first(i); }
+//     //ROSSZ template<typename I, typename P> I& first(I& i, const P& p) const { 
+//     //  return first(i, p); }
+    
+//     //template<typename I> I getNext(const I& i) const { 
+//     //  return gw.getNext(i); }
+//     //template<typename I> I& next(I &i) const { return gw.next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     //Node head(const Edge& e) const { return gw.head(e); }
+//     //Node tail(const Edge& e) const { return gw.tail(e); }
+
+//     //template<typename I> bool valid(const I& i) const 
+//     //  { return gw.valid(i); }
+  
+//     //int nodeNum() const { return gw.nodeNum(); }
+//     //int edgeNum() const { return gw.edgeNum(); }
+  
+//     //template<typename I> Node aNode(const I& e) const { 
+//     //  return gw.aNode(e); }
+//     //template<typename I> Node bNode(const I& e) const { 
+//     //  return gw.bNode(e); }
+  
+//     //Node addNode() const { return gw.addNode(); }
+//     //Edge addEdge(const Node& tail, const Node& head) const { 
+//     //  return gw.addEdge(tail, head); }
+  
+//     //void erase(const OutEdgeIt& e) {
+//     //  first_out_edge(this->tail(e))=e;
+//     //}
+//     void erase(const Edge& e) {
+//       OutEdgeIt f(e);
+//       next(f);
+//       first_out_edges.set(this->tail(e), f);
+//     }
+//     //template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//     //void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T> { 
+//     public:
+//       NodeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/) { }
+//       NodeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G, T a) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/) { }
+//       EdgeMap(const ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>& _G, T a) : 
+// 	ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+//   };
+
+//   template<typename GraphWrapper> 
+//   class FilterGraphWrapper {
+//   };
+
+//   template<typename Graph, typename Number, typename FlowMap, typename CapacityMap>
+//   class FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> > : public ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> {
+
+//     //Graph* graph;
+  
+//   public:
+//     //typedef Graph BaseGraph;
+
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Node Node;
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeIt NodeIt;
+
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::Edge Edge;
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt OutEdgeIt;
+//     //typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::InEdgeIt InEdgeIt;
+//     //typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeIt EdgeIt;
+
+//     //FilterGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<typename ResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::OutEdgeIt> first_out_edges;
+    
+//   public:
+//     FilterGraphWrapper(const Graph& _G, FlowMap& _flow, 
+// 			   const CapacityMap& _capacity) : 
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>(_G, _flow, _capacity), dist(*this, gw.nodeNum()) { 
+//     }
+
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const {
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(e, n);
+//       while (valid(e) && (dist.get(tail(e))/*+1!=*/>=dist.get(head(e)))) 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//       return e;
+//     }
+
+//     NodeIt& next(NodeIt& e) const {
+//       return ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//     }
+
+//     OutEdgeIt& next(OutEdgeIt& e) const {
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//       while (valid(e) && (dist.get(tail(e))/*+1!*/>=dist.get(head(e)))) 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(e);
+//       return e;
+//     }
+
+//     NodeIt& first(NodeIt& n) const {
+//       return ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::first(n);
+//     }
+
+//     void erase(const Edge& e) {
+//       OutEdgeIt f(e);
+//       ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(f);
+//       while (valid(f) && (dist.get(tail(f))/*+1!=*/>=dist.get(head(f)))) 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::next(f);
+//       first_out_edges.set(this->tail(e), f);
+//     }
+
+//     //TrivGraphWrapper() : graph(0) { }
+//     //TrivGraphWrapper(Graph& _graph) : graph(&_graph) { }
+
+//     //void setGraph(Graph& _graph) { graph = &_graph; }
+//     //Graph& getGraph() const { return (*graph); }
+    
+//     //template<typename I> I& first(I& i) const { return gw.first(i); }
+//     //template<typename I, typename P> I& first(I& i, const P& p) const { 
+//     //  return gw.first(i, p); }
+    
+//     //template<typename I> I getNext(const I& i) const { 
+//     //  return gw.getNext(i); }
+//     //template<typename I> I& next(I &i) const { return gw.next(i); }    
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(const Node& v) const { 
+//       It e; first(e, v); return e; }
+
+//     //Node head(const Edge& e) const { return gw.head(e); }
+//     //Node tail(const Edge& e) const { return gw.tail(e); }
+
+//     //template<typename I> bool valid(const I& i) const 
+//     //  { return gw.valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return gw.setInvalid(i); }
+
+//     //int nodeNum() const { return gw.nodeNum(); }
+//     //int edgeNum() const { return gw.edgeNum(); }
+  
+//     //template<typename I> Node aNode(const I& e) const { 
+//     //  return gw.aNode(e); }
+//     //template<typename I> Node bNode(const I& e) const { 
+//     //  return gw.bNode(e); }
+  
+//     //Node addNode() const { return gw.addNode(); }
+//     //Edge addEdge(const Node& tail, const Node& head) const { 
+//     //  return gw.addEdge(tail, head); }
+  
+//     //template<typename I> void erase(const I& i) const { gw.erase(i); }
+  
+//     //void clear() const { gw.clear(); }
+    
+//     template<typename T> class NodeMap : public ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T> { 
+//     public:
+//       NodeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/) { }
+//       NodeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G, T a) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+
+//     template<typename T> class EdgeMap : public ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T> { 
+//     public:
+//       EdgeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/) { }
+//       EdgeMap(const FilterGraphWrapper<ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap> >& _G, T a) : 
+// 	ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::EdgeMap<T>(_G /*_G.getGraph()*/, a) { }
+//     };
+
+//   public:
+//     ErasingResGraphWrapper<Graph, Number, FlowMap, CapacityMap>::NodeMap<int> dist;
+
+//   };
+
+
+
+// // FIXME: comparison should be made better!!!
+//   template<typename Graph, typename T, typename LowerMap, typename FlowMap, typename UpperMap>
+//   class ResGraphWrapper
+//   {
+//     Graph* graph;
+  
+//   public:
+//     typedef Graph BaseGraph;
+
+//     typedef typename Graph::Node Node;
+//     typedef typename Graph::Edge Edge;
+  
+//     typedef typename Graph::NodeIt NodeIt;
+   
+//     class OutEdgeIt {
+//     public:
+//       //Graph::Node n;
+//       bool out_or_in;
+//       typename Graph::OutEdgeIt o;
+//       typename Graph::InEdgeIt i;   
+//     };
+//     class InEdgeIt {
+//     public:
+//       //Graph::Node n;
+//       bool out_or_in;
+//       typename Graph::OutEdgeIt o;
+//       typename Graph::InEdgeIt i;   
+//     };
+//     typedef typename Graph::SymEdgeIt SymEdgeIt;
+//     typedef typename Graph::EdgeIt EdgeIt;
+
+//     int nodeNum() const { return gw.nodeNum(); }
+//     int edgeNum() const { return gw.edgeNum(); }
+
+//     Node& first(Node& n) const { return gw.first(n); }
+
+//     // Edge and SymEdge  is missing!!!!
+//     // Edge <-> In/OutEdgeIt conversion is missing!!!!
+
+//     //FIXME
+//     OutEdgeIt& first(OutEdgeIt& e, const Node& n) const 
+//       {
+// 	e.n=n;
+// 	gw.first(e.o,n);
+// 	while(gw.valid(e.o) && fmap.get(e.o)>=himap.get(e.o))
+// 	  gw.goNext(e.o);
+// 	if(!gw.valid(e.o)) {
+// 	  gw.first(e.i,n);
+// 	  while(gw.valid(e.i) && fmap.get(e.i)<=lomap.get(e.i))
+// 	    gw.goNext(e.i);
+// 	}
+// 	return e;
+//       }
+// /*
+//   OutEdgeIt &goNext(OutEdgeIt &e)
+//   {
+//   if(gw.valid(e.o)) {
+//   while(gw.valid(e.o) && fmap.get(e.o)>=himap.get(e.o))
+//   gw.goNext(e.o);
+//   if(gw.valid(e.o)) return e;
+//   else gw.first(e.i,e.n);
+//   }
+//   else {
+//   while(gw.valid(e.i) && fmap.get(e.i)<=lomap.get(e.i))
+//   gw.goNext(e.i);
+//   return e;
+//   }
+//   }
+//   OutEdgeIt Next(const OutEdgeIt &e) {OutEdgeIt t(e); return goNext(t);}
+// */
+//     //bool valid(const OutEdgeIt e) { return gw.valid(e.o)||gw.valid(e.i);}
+
+//     //FIXME
+//     InEdgeIt& first(InEdgeIt& e, const Node& n) const 
+//       {
+// 	e.n=n;
+// 	gw.first(e.i,n);
+// 	while(gw.valid(e.i) && fmap.get(e.i)>=himap.get(e.i))
+// 	  gw.goNext(e.i);
+// 	if(!gw.valid(e.i)) {
+// 	  gw.first(e.o,n);
+// 	  while(gw.valid(e.o) && fmap.get(e.o)<=lomap.get(e.o))
+// 	    gw.goNext(e.o);
+// 	}
+// 	return e;
+//       }
+// /*
+//   InEdgeIt &goNext(InEdgeIt &e)
+//   {
+//   if(gw.valid(e.i)) {
+//   while(gw.valid(e.i) && fmap.get(e.i)>=himap.get(e.i))
+//   gw.goNext(e.i);
+//   if(gw.valid(e.i)) return e;
+//   else gw.first(e.o,e.n);
+//   }
+//   else {
+//   while(gw.valid(e.o) && fmap.get(e.o)<=lomap.get(e.o))
+//   gw.goNext(e.o);
+//   return e;
+//   }
+//   }
+//   InEdgeIt Next(const InEdgeIt &e) {InEdgeIt t(e); return goNext(t);}
+// */
+//     //bool valid(const InEdgeIt e) { return gw.valid(e.i)||gw.valid(e.o);}
+
+//     //template<typename I> I &goNext(I &i); { return gw.goNext(i); }
+//     //template<typename I> I next(const I i); { return gw.goNext(i); }
+
+//     template< typename It > It first() const { 
+//       It e; first(e); return e; }
+
+//     template< typename It > It first(Node v) const { 
+//       It e; first(e, v); return e; }
+
+//     Node head(const Edge& e) const { return gw.head(e); }
+//     Node tail(const Edge& e) const { return gw.tail(e); }
+  
+//     template<typename I> Node aNode(const I& e) const { 
+//       return gw.aNode(e); }
+//     template<typename I> Node bNode(const I& e) const { 
+//       return gw.bNode(e); }
+  
+//     //template<typename I> bool valid(const I i);
+//     //{ return gw.valid(i); }
+  
+//     //template<typename I> void setInvalid(const I &i);
+//     //{ return gw.setInvalid(i); }
+  
+//     Node addNode() { return gw.addNode(); }
+//     Edge addEdge(const Node& tail, const Node& head) { 
+//       return gw.addEdge(tail, head); }
+  
+//     template<typename I> void erase(const I& i) { gw.erase(i); }
+  
+//     void clear() { gw.clear(); }
+  
+//     template<typename S> class NodeMap : public Graph::NodeMap<S> { };
+//     template<typename S> class EdgeMap : public Graph::EdgeMap<S> { };
+  
+//     void setGraph(Graph& _graph) { graph = &_graph; }
+//     Graph& getGraph() { return (*graph); }
+
+//     //ResGraphWrapper() : graph(0) { }
+//     ResGraphWrapper(Graph& _graph) : graph(&_graph) { }
+//   };
+
+} //namespace hugo
+
+#endif //HUGO_GRAPH_WRAPPER_H
+

Added: hugo/trunk/src/work/marci/experiment/iterator_bfs_demo.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/iterator_bfs_demo.cc	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,322 @@
+// -*- c++ -*-
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include <list_graph.h>
+//#include <smart_graph.h>
+#include <bfs_iterator_1.h>
+#include <graph_wrapper_1.h>
+
+using namespace hugo;
+using std::cout; 
+using std::endl;
+using std::string;
+
+template <typename Graph, typename NodeNameMap>
+class EdgeNameMap {
+  Graph& graph;
+  NodeNameMap& node_name_map;
+public:
+  EdgeNameMap(Graph& _graph, NodeNameMap& _node_name_map) : 
+    graph(_graph), node_name_map(_node_name_map) { }
+  string get(typename Graph::Edge e) const { 
+    return 
+      (node_name_map.get(graph.tail(e))+"->"+node_name_map.get(graph.head(e)));
+  }
+};
+
+int main (int, char*[])
+{
+  //typedef SmartGraph Graph;
+  typedef ListGraph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+ 
+  Graph G;
+
+  Node s=G.addNode();
+  Node v1=G.addNode();
+  Node v2=G.addNode();
+  Node v3=G.addNode();
+  Node v4=G.addNode();
+  Node t=G.addNode();
+  
+  Graph::NodeMap<string> node_name(G);
+  node_name.set(s, "s");
+  node_name.set(v1, "v1");
+  node_name.set(v2, "v2");
+  node_name.set(v3, "v3");
+  node_name.set(v4, "v4");
+  node_name.set(t, "t");
+
+  G.addEdge(s, v1);
+  G.addEdge(s, v2);
+  G.addEdge(v1, v2);
+  G.addEdge(v2, v1);
+  G.addEdge(v1, v3);
+  G.addEdge(v3, v2);
+  G.addEdge(v2, v4);
+  G.addEdge(v4, v3);
+  G.addEdge(v3, t);
+  G.addEdge(v4, t);
+
+  cout << "    /-->    ------------->            "<< endl;
+  cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+  cout << "  / |          |    /  /->     \\     "<< endl;
+  cout << " /  |          |   /  |    ^    \\  "<< endl;
+  cout << "s   |          |  /   |    |     \\->  t "<< endl;
+  cout << " \\  |          | /    |    |     /->  "<< endl;
+  cout << "  \\ |       --/ /     |    |    /     "<< endl;
+  cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+  cout << "    \\-->    ------------->         "<< endl;
+  
+//   typedef TrivGraphWrapper<const Graph> CGW;
+//   CGW gw(G);
+
+//   cout << "bfs and dfs demo on the directed graph" << endl;
+//   for(CGW::NodeIt n=gw.first<CGW::NodeIt>(); n.valid(); ++n) { 
+//     cout << n << ": ";
+//     cout << "out edges: ";
+//     for(CGW::OutEdgeIt e=gw.first<CGW::OutEdgeIt>(n); e.valid(); ++e) 
+//       cout << e << " ";
+//     cout << "in edges: ";
+//     for(CGW::InEdgeIt e=gw.first<CGW::InEdgeIt>(n); e.valid(); ++e) 
+//       cout << e << " ";
+//     cout << endl;
+//   }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+
+    EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+    
+    cout << "bfs and dfs iterator demo on the directed graph" << endl;
+    for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
+      cout << node_name.get(n) << ": ";
+      cout << "out edges: ";
+      for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << "in edges: ";
+      for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << endl;
+    }
+
+    cout << "bfs from s ..." << endl;
+    BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
+    bfs.pushAndSetReached(s);
+    while (!bfs.finished()) {
+      //cout << "edge: ";
+      if (gw.valid(bfs)) {
+	cout << edge_name.get(bfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(bfs)) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(bfs)) << 
+	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(bfs.aNode()) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+      ++bfs;
+    }
+
+    cout << "    /-->    ------------->            "<< endl;
+    cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+    cout << "  / |          |    /  /->     \\     "<< endl;
+    cout << " /  |          |   /  |    ^    \\  "<< endl;
+    cout << "s   |          |  /   |    |     \\->  t "<< endl;
+    cout << " \\  |          | /    |    |     /->  "<< endl;
+    cout << "  \\ |       --/ /     |    |    /     "<< endl;
+    cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+    cout << "    \\-->    ------------->         "<< endl;
+
+    cout << "dfs from s ..." << endl;
+    DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
+    dfs.pushAndSetReached(s);
+    while (!dfs.finished()) {
+      ++dfs;
+      //cout << "edge: ";
+      if (gw.valid(dfs)) {
+	cout << edge_name.get(dfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(dfs)) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(dfs)) << 
+	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(dfs.aNode()) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+    }
+  }
+
+
+  {
+    typedef RevGraphWrapper<const TrivGraphWrapper<const Graph> > GW;
+    GW gw(G);
+    
+    EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+    
+    cout << "bfs and dfs iterator demo on the reversed directed graph" << endl;
+    for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
+      cout << node_name.get(n) << ": ";
+      cout << "out edges: ";
+      for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << "in edges: ";
+      for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << endl;
+    }
+
+    cout << "bfs from t ..." << endl;
+    BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
+    bfs.pushAndSetReached(t);
+    while (!bfs.finished()) {
+      //cout << "edge: ";
+      if (gw.valid(bfs)) {
+	cout << edge_name.get(bfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(bfs)) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(bfs)) << 
+	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(bfs.aNode()) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+      ++bfs;
+    }
+
+    cout << "    /-->    ------------->            "<< endl;
+    cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+    cout << "  / |          |    /  /->     \\     "<< endl;
+    cout << " /  |          |   /  |    ^    \\  "<< endl;
+    cout << "s   |          |  /   |    |     \\->  t "<< endl;
+    cout << " \\  |          | /    |    |     /->  "<< endl;
+    cout << "  \\ |       --/ /     |    |    /     "<< endl;
+    cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+    cout << "    \\-->    ------------->         "<< endl;
+    
+    cout << "dfs from t ..." << endl;
+    DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
+    dfs.pushAndSetReached(t);
+    while (!dfs.finished()) {
+      ++dfs;
+      //cout << "edge: ";
+      if (gw.valid(dfs)) {
+	cout << edge_name.get(dfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(dfs)) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(dfs)) << 
+	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(dfs.aNode()) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+    }
+  }
+
+  {
+    //typedef UndirGraphWrapper<const Graph> GW;
+    typedef UndirGraphWrapper<const TrivGraphWrapper<const Graph> > GW;
+    GW gw(G);
+    
+    EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+    
+    cout << "bfs and dfs iterator demo on the undirected graph" << endl;
+    for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
+      cout << node_name.get(n) << ": ";
+      cout << "out edges: ";
+      for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << "in edges: ";
+      for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << endl;
+    }
+//     for(GW::EdgeIt e=gw.first<GW::EdgeIt>(); gw.valid(e); gw.next(e)) { 
+//       cout << edge_name.get(e) << " ";
+//     }
+//     cout << endl;
+
+    cout << "bfs from t ..." << endl;
+    BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
+    bfs.pushAndSetReached(t);
+    while (!bfs.finished()) {
+      //cout << "edge: ";
+      if (gw.valid(GW::OutEdgeIt(bfs))) {
+	cout << edge_name.get(GW::OutEdgeIt(bfs)) << /*endl*/", " << 
+	  node_name.get(gw.aNode(bfs)) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(bfs)) << 
+	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(bfs.aNode()) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+      ++bfs;
+    }
+
+    cout << "    /-->    ------------->            "<< endl;
+    cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+    cout << "  / |          |    /  /->     \\     "<< endl;
+    cout << " /  |          |   /  |    ^    \\  "<< endl;
+    cout << "s   |          |  /   |    |     \\->  t "<< endl;
+    cout << " \\  |          | /    |    |     /->  "<< endl;
+    cout << "  \\ |       --/ /     |    |    /     "<< endl;
+    cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+    cout << "    \\-->    ------------->         "<< endl;
+    
+    cout << "dfs from t ..." << endl;
+    DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
+    dfs.pushAndSetReached(t);
+    while (!dfs.finished()) {
+      ++dfs;
+      //cout << "edge: ";
+      if (gw.valid(GW::OutEdgeIt(dfs))) {
+	cout << edge_name.get(GW::OutEdgeIt(dfs)) << /*endl*/", " << 
+	  node_name.get(gw.aNode(dfs)) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(dfs)) << 
+	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(dfs.aNode()) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+    }
+  }
+
+  return 0;
+}

Added: hugo/trunk/src/work/marci/experiment/iterator_bfs_demo_1.cc
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/iterator_bfs_demo_1.cc	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,322 @@
+// -*- c++ -*-
+#include <iostream>
+#include <vector>
+#include <string>
+
+#include <list_graph.h>
+#include <smart_graph.h>
+#include <bfs_iterator.h>
+#include <graph_wrapper.h>
+
+using namespace hugo;
+using std::cout; 
+using std::endl;
+using std::string;
+
+template <typename Graph, typename NodeNameMap>
+class EdgeNameMap {
+  Graph& graph;
+  NodeNameMap& node_name_map;
+public:
+  EdgeNameMap(Graph& _graph, NodeNameMap& _node_name_map) : 
+    graph(_graph), node_name_map(_node_name_map) { }
+  string get(typename Graph::Edge e) const { 
+    return 
+      (node_name_map.get(graph.tail(e))+"->"+node_name_map.get(graph.head(e)));
+  }
+};
+
+int main (int, char*[])
+{
+  //typedef SmartGraph Graph;
+  typedef ListGraph Graph;
+
+  typedef Graph::Node Node;
+  typedef Graph::Edge Edge;
+ 
+  Graph G;
+
+  Node s=G.addNode();
+  Node v1=G.addNode();
+  Node v2=G.addNode();
+  Node v3=G.addNode();
+  Node v4=G.addNode();
+  Node t=G.addNode();
+  
+  Graph::NodeMap<string> node_name(G);
+  node_name.set(s, "s");
+  node_name.set(v1, "v1");
+  node_name.set(v2, "v2");
+  node_name.set(v3, "v3");
+  node_name.set(v4, "v4");
+  node_name.set(t, "t");
+
+  G.addEdge(s, v1);
+  G.addEdge(s, v2);
+  G.addEdge(v1, v2);
+  G.addEdge(v2, v1);
+  G.addEdge(v1, v3);
+  G.addEdge(v3, v2);
+  G.addEdge(v2, v4);
+  G.addEdge(v4, v3);
+  G.addEdge(v3, t);
+  G.addEdge(v4, t);
+
+  cout << "    /-->    ------------->            "<< endl;
+  cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+  cout << "  / |          |    /  /->     \\     "<< endl;
+  cout << " /  |          |   /  |    ^    \\  "<< endl;
+  cout << "s   |          |  /   |    |     \\->  t "<< endl;
+  cout << " \\  |          | /    |    |     /->  "<< endl;
+  cout << "  \\ |       --/ /     |    |    /     "<< endl;
+  cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+  cout << "    \\-->    ------------->         "<< endl;
+  
+//   typedef TrivGraphWrapper<const Graph> CGW;
+//   CGW gw(G);
+
+//   cout << "bfs and dfs demo on the directed graph" << endl;
+//   for(CGW::NodeIt n=gw.first<CGW::NodeIt>(); n.valid(); ++n) { 
+//     cout << n << ": ";
+//     cout << "out edges: ";
+//     for(CGW::OutEdgeIt e=gw.first<CGW::OutEdgeIt>(n); e.valid(); ++e) 
+//       cout << e << " ";
+//     cout << "in edges: ";
+//     for(CGW::InEdgeIt e=gw.first<CGW::InEdgeIt>(n); e.valid(); ++e) 
+//       cout << e << " ";
+//     cout << endl;
+//   }
+
+  {
+    typedef TrivGraphWrapper<const Graph> GW;
+    GW gw(G);
+
+    EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+    
+    cout << "bfs and dfs iterator demo on the directed graph" << endl;
+    for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
+      cout << node_name.get(n) << ": ";
+      cout << "out edges: ";
+      for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << "in edges: ";
+      for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << endl;
+    }
+
+    cout << "bfs from s ..." << endl;
+    BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
+    bfs.pushAndSetReached(s);
+    while (!bfs.finished()) {
+      //cout << "edge: ";
+      if (gw.valid(bfs)) {
+	cout << edge_name.get(bfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(bfs)) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(bfs)) << 
+	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(bfs.aNode()) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+      ++bfs;
+    }
+
+    cout << "    /-->    ------------->            "<< endl;
+    cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+    cout << "  / |          |    /  /->     \\     "<< endl;
+    cout << " /  |          |   /  |    ^    \\  "<< endl;
+    cout << "s   |          |  /   |    |     \\->  t "<< endl;
+    cout << " \\  |          | /    |    |     /->  "<< endl;
+    cout << "  \\ |       --/ /     |    |    /     "<< endl;
+    cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+    cout << "    \\-->    ------------->         "<< endl;
+
+    cout << "dfs from s ..." << endl;
+    DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
+    dfs.pushAndSetReached(s);
+    while (!dfs.finished()) {
+      ++dfs;
+      //cout << "edge: ";
+      if (gw.valid(dfs)) {
+	cout << edge_name.get(dfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(dfs)) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(dfs)) << 
+	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(dfs.aNode()) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+    }
+  }
+
+
+  {
+    typedef RevGraphWrapper<const TrivGraphWrapper<const Graph> > GW;
+    GW gw(G);
+    
+    EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+    
+    cout << "bfs and dfs iterator demo on the reversed directed graph" << endl;
+    for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
+      cout << node_name.get(n) << ": ";
+      cout << "out edges: ";
+      for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << "in edges: ";
+      for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << endl;
+    }
+
+    cout << "bfs from t ..." << endl;
+    BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
+    bfs.pushAndSetReached(t);
+    while (!bfs.finished()) {
+      //cout << "edge: ";
+      if (gw.valid(bfs)) {
+	cout << edge_name.get(bfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(bfs)) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(bfs)) << 
+	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(bfs.aNode()) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+      ++bfs;
+    }
+
+    cout << "    /-->    ------------->            "<< endl;
+    cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+    cout << "  / |          |    /  /->     \\     "<< endl;
+    cout << " /  |          |   /  |    ^    \\  "<< endl;
+    cout << "s   |          |  /   |    |     \\->  t "<< endl;
+    cout << " \\  |          | /    |    |     /->  "<< endl;
+    cout << "  \\ |       --/ /     |    |    /     "<< endl;
+    cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+    cout << "    \\-->    ------------->         "<< endl;
+    
+    cout << "dfs from t ..." << endl;
+    DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
+    dfs.pushAndSetReached(t);
+    while (!dfs.finished()) {
+      ++dfs;
+      //cout << "edge: ";
+      if (gw.valid(dfs)) {
+	cout << edge_name.get(dfs) << /*endl*/", " << 
+	  node_name.get(gw.aNode(dfs)) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(dfs)) << 
+	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(dfs.aNode()) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+    }
+  }
+
+  {
+    //typedef UndirGraphWrapper<const Graph> GW;
+    typedef UndirGraphWrapper<const TrivGraphWrapper<const Graph> > GW;
+    GW gw(G);
+    
+    EdgeNameMap< GW, Graph::NodeMap<string> > edge_name(gw, node_name);
+    
+    cout << "bfs and dfs iterator demo on the undirected graph" << endl;
+    for(GW::NodeIt n(gw); gw.valid(n); gw.next(n)) { 
+      cout << node_name.get(n) << ": ";
+      cout << "out edges: ";
+      for(GW::OutEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << "in edges: ";
+      for(GW::InEdgeIt e(gw, n); gw.valid(e); gw.next(e)) 
+	cout << edge_name.get(e) << " ";
+      cout << endl;
+    }
+//     for(GW::EdgeIt e=gw.first<GW::EdgeIt>(); gw.valid(e); gw.next(e)) { 
+//       cout << edge_name.get(e) << " ";
+//     }
+//     cout << endl;
+
+    cout << "bfs from t ..." << endl;
+    BfsIterator5< GW, GW::NodeMap<bool> > bfs(gw);
+    bfs.pushAndSetReached(t);
+    while (!bfs.finished()) {
+      //cout << "edge: ";
+      if (gw.valid(GW::OutEdgeIt(bfs))) {
+	cout << edge_name.get(GW::OutEdgeIt(bfs)) << /*endl*/", " << 
+	  node_name.get(gw.aNode(bfs)) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(bfs)) << 
+	  (bfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(bfs.aNode()) << 
+	  (bfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+      ++bfs;
+    }
+
+    cout << "    /-->    ------------->            "<< endl;
+    cout << "   / /-- v1 <-\\      /---- v3-\\      "<< endl;
+    cout << "  / |          |    /  /->     \\     "<< endl;
+    cout << " /  |          |   /  |    ^    \\  "<< endl;
+    cout << "s   |          |  /   |    |     \\->  t "<< endl;
+    cout << " \\  |          | /    |    |     /->  "<< endl;
+    cout << "  \\ |       --/ /     |    |    /     "<< endl;
+    cout << "   \\ \\-> v2 <--/       \\-- v4 -/      "<< endl;
+    cout << "    \\-->    ------------->         "<< endl;
+    
+    cout << "dfs from t ..." << endl;
+    DfsIterator5< GW, GW::NodeMap<bool> > dfs(gw);
+    dfs.pushAndSetReached(t);
+    while (!dfs.finished()) {
+      ++dfs;
+      //cout << "edge: ";
+      if (gw.valid(GW::OutEdgeIt(dfs))) {
+	cout << edge_name.get(GW::OutEdgeIt(dfs)) << /*endl*/", " << 
+	  node_name.get(gw.aNode(dfs)) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  node_name.get(gw.bNode(dfs)) << 
+	  (dfs.isBNodeNewlyReached() ? ": is newly reached." : 
+	   ": is not newly reached.");
+      } else { 
+	cout << "invalid" << /*endl*/", " << 
+	  node_name.get(dfs.aNode()) << 
+	  (dfs.isANodeExamined() ? ": is examined, " : ": is not examined, ") << 
+	  
+	  "invalid.";
+      }
+      cout << endl;
+    }
+  }
+
+  return 0;
+}

Added: hugo/trunk/src/work/marci/experiment/list_graph.h
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/list_graph.h	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,570 @@
+// -*- c++ -*-
+#ifndef HUGO_LIST_GRAPH_H
+#define HUGO_LIST_GRAPH_H
+
+#include <iostream>
+#include <vector>
+
+#include <invalid.h>
+
+namespace hugo {
+
+  template <typename It>
+  int count(It it) { 
+    int i=0;
+    for( ; it.valid(); ++it) { ++i; } 
+    return i;
+  }
+
+  class ListGraph {
+    class node_item;
+    class edge_item;
+  public:
+    class Node;
+    class NodeIt;
+    class Edge;
+    class EdgeIt;
+    class OutEdgeIt;
+    class InEdgeIt;
+    class SymEdgeIt;
+    template <typename T> class NodeMap;
+    template <typename T> class EdgeMap;
+  private:
+    template <typename T> friend class NodeMap;
+    template <typename T> friend class EdgeMap;
+ 
+    template <typename T>
+    class NodeMap {
+      const ListGraph& G; 
+      std::vector<T> container;
+    public:
+      typedef T ValueType;
+      typedef Node KeyType;
+      NodeMap(const ListGraph& _G) : G(_G), container(G.node_id) { }
+      NodeMap(const ListGraph& _G, T a) : 
+	G(_G), container(G.node_id, a) { }
+      void set(Node n, T a) { container[/*G.id(n)*/n.node->id]=a; }
+      T get(Node n) const { return container[/*G.id(n)*/n.node->id]; }
+      typename std::vector<T>::reference operator[](Node n) { 
+	return container[/*G.id(n)*/n.node->id]; }
+      typename std::vector<T>::const_reference operator[](Node n) const { 
+	return container[/*G.id(n)*/n.node->id]; 
+      }
+      void update() { container.resize(G.node_id); }
+      void update(T a) { container.resize(G.node_id, a); }
+    };
+
+    template <typename T>
+    class EdgeMap {
+      const ListGraph& G; 
+      std::vector<T> container;
+    public:
+      typedef T ValueType;
+      typedef Edge KeyType;
+      EdgeMap(const ListGraph& _G) : G(_G), container(G.edge_id) { }
+      EdgeMap(const ListGraph& _G, T a) : 
+	G(_G), container(G.edge_id, a) { }
+      void set(Edge e, T a) { container[/*G.id(e)*/e.edge->id]=a; }
+      T get(Edge e) const { return container[/*G.id(e)*/e.edge->id]; }
+      typename std::vector<T>::reference operator[](Edge e) { 
+	return container[/*G.id(e)*/e.edge->id]; } 
+      typename std::vector<T>::const_reference operator[](Edge e) const { 
+	return container[/*G.id(e)*/e.edge->id]; 
+      } 
+      void update() { container.resize(G.edge_id); }
+      void update(T a) { container.resize(G.edge_id, a); }
+    };
+
+    int node_id;
+    int edge_id;
+    int _node_num;
+    int _edge_num;
+
+    node_item* _first_node;
+    node_item* _last_node;
+
+    class node_item {
+      friend class ListGraph;
+      template <typename T> friend class NodeMap;
+      
+      friend class Node;
+      friend class NodeIt;
+      friend class Edge;
+      friend class EdgeIt;
+      friend class OutEdgeIt;
+      friend class InEdgeIt;
+      friend class SymEdgeIt;
+      friend std::ostream& operator<<(std::ostream& os, const Node& i);
+      friend std::ostream& operator<<(std::ostream& os, const Edge& i);
+      //ListGraph* G;
+      int id;
+      edge_item* _first_out_edge;
+      edge_item* _last_out_edge;
+      edge_item* _first_in_edge;
+      edge_item* _last_in_edge;
+      node_item* _next_node;
+      node_item* _prev_node;
+    public:
+      node_item() { }
+    };
+
+    class edge_item {
+      friend class ListGraph;
+      template <typename T> friend class EdgeMap;
+
+      friend class Node;
+      friend class NodeIt;
+      friend class Edge;
+      friend class EdgeIt;
+      friend class OutEdgeIt;
+      friend class InEdgeIt;
+      friend class SymEdgeIt;
+      friend std::ostream& operator<<(std::ostream& os, const Edge& i);
+      //ListGraph* G;
+      int id;
+      node_item* _tail;
+      node_item* _head;
+      edge_item* _next_out;
+      edge_item* _prev_out;
+      edge_item* _next_in;
+      edge_item* _prev_in;
+    public:
+      edge_item() { }
+    };
+
+    node_item* _add_node() { 
+      node_item* p=new node_item;
+      p->id=node_id++;
+      p->_first_out_edge=0;
+      p->_last_out_edge=0;
+      p->_first_in_edge=0;
+      p->_last_in_edge=0;
+      p->_prev_node=_last_node;
+      p->_next_node=0;
+      if (_last_node) _last_node->_next_node=p;
+      _last_node=p;
+      if (!_first_node) _first_node=p;
+
+      ++_node_num;
+      return p;
+    }
+
+    edge_item* _add_edge(node_item* _tail, node_item* _head) {
+      edge_item* e=new edge_item;
+      e->id=edge_id++;
+      e->_tail=_tail;
+      e->_head=_head;
+      
+      e->_prev_out=_tail->_last_out_edge;
+      if (_tail->_last_out_edge) (_tail->_last_out_edge)->_next_out=e;
+      _tail->_last_out_edge=e;
+      if (!_tail->_first_out_edge) _tail->_first_out_edge=e; 
+      e->_next_out=0;
+ 
+      e->_prev_in=_head->_last_in_edge;
+      if (_head->_last_in_edge) (_head->_last_in_edge)->_next_in=e;
+      _head->_last_in_edge=e;
+      if (!_head->_first_in_edge) { _head->_first_in_edge=e; } 
+      e->_next_in=0;
+
+      ++_edge_num;
+      return e;
+    }
+
+    //deletes a node which has no out edge and no in edge
+    void _delete_node(node_item* v) {
+      if (v->_next_node) (v->_next_node)->_prev_node=v->_prev_node; else 
+	_last_node=v->_prev_node;
+      if (v->_prev_node) (v->_prev_node)->_next_node=v->_next_node; else 
+	_first_node=v->_next_node;
+
+      delete v;
+      --_node_num;
+    }
+
+    void _delete_edge(edge_item* e) {
+      if (e->_next_out) (e->_next_out)->_prev_out=e->_prev_out; else 
+	(e->_tail)->_last_out_edge=e->_prev_out;
+      if (e->_prev_out) (e->_prev_out)->_next_out=e->_next_out; else 
+	(e->_tail)->_first_out_edge=e->_next_out;
+      if (e->_next_in) (e->_next_in)->_prev_in=e->_prev_in; else 
+	(e->_head)->_last_in_edge=e->_prev_in;
+      if (e->_prev_in) (e->_prev_in)->_next_in=e->_next_in; else 
+	(e->_head)->_first_in_edge=e->_next_in;
+
+      delete e;
+      --_edge_num;
+    }
+
+    void _set_tail(edge_item* e, node_item* _tail) {
+      if (e->_next_out) (e->_next_out)->_prev_out=e->_prev_out; else 
+	(e->_tail)->_last_out_edge=e->_prev_out;
+      if (e->_prev_out) (e->_prev_out)->_next_out=e->_next_out; else 
+	(e->_tail)->_first_out_edge=e->_next_out;
+      
+      e->_tail=_tail;
+      
+      e->_prev_out=_tail->_last_out_edge;
+      if (_tail->_last_out_edge) (_tail->_last_out_edge)->_next_out=e;
+      _tail->_last_out_edge=e;
+      if (!_tail->_first_out_edge) _tail->_first_out_edge=e; 
+      e->_next_out=0;
+    }
+
+    void _set_head(edge_item* e, node_item* _head) {
+      if (e->_next_in) (e->_next_in)->_prev_in=e->_prev_in; else 
+	(e->_head)->_last_in_edge=e->_prev_in;
+      if (e->_prev_in) (e->_prev_in)->_next_in=e->_next_in; else 
+	(e->_head)->_first_in_edge=e->_next_in;
+      
+      e->_head=_head;
+      
+      e->_prev_in=_head->_last_in_edge;
+      if (_head->_last_in_edge) (_head->_last_in_edge)->_next_in=e;
+      _head->_last_in_edge=e;
+      if (!_head->_first_in_edge) { _head->_first_in_edge=e; } 
+      e->_next_in=0;
+    }
+
+  public:
+
+    /* default constructor */
+
+    ListGraph() : node_id(0), edge_id(0), _node_num(0), _edge_num(0), _first_node(0), _last_node(0) { }
+    
+    ~ListGraph() { 
+      while (first<NodeIt>().valid()) erase(first<NodeIt>());
+    }
+
+    int nodeNum() const { return _node_num; }
+    int edgeNum() const { return _edge_num; }
+
+    /* functions to construct iterators from the graph, or from each other */
+
+    //NodeIt firstNode() const { return NodeIt(*this); }
+    //EdgeIt firstEdge() const { return EdgeIt(*this); }
+    
+    //OutEdgeIt firstOutEdge(const Node v) const { return OutEdgeIt(v); }
+    //InEdgeIt firstInEdge(const Node v) const { return InEdgeIt(v); }
+    //SymEdgeIt firstSymEdge(const Node v) const { return SymEdgeIt(v); }
+    Node tail(Edge e) const { return e.tailNode(); }
+    Node head(Edge e) const { return e.headNode(); }
+
+    Node aNode(const OutEdgeIt& e) const { return e.aNode(); }
+    Node aNode(const InEdgeIt& e) const { return e.aNode(); }
+    Node aNode(const SymEdgeIt& e) const { return e.aNode(); }
+
+    Node bNode(const OutEdgeIt& e) const { return e.bNode(); }
+    Node bNode(const InEdgeIt& e) const { return e.bNode(); }
+    Node bNode(const SymEdgeIt& e) const { return e.bNode(); }
+
+    //Node invalid_node() { return Node(); }
+    //Edge invalid_edge() { return Edge(); }
+    //OutEdgeIt invalid_out_edge() { return OutEdgeIt(); }
+    //InEdgeIt invalid_in_edge() { return InEdgeIt(); }
+    //SymEdgeIt invalid_sym_edge() { return SymEdgeIt(); }
+
+    /* same methods in other style */
+    /* for experimental purpose */
+
+    NodeIt& /*getF*/first(NodeIt& v) const { 
+      v=NodeIt(*this); return v; }
+    EdgeIt& /*getF*/first(EdgeIt& e) const { 
+      e=EdgeIt(*this); return e; }
+    OutEdgeIt& /*getF*/first(OutEdgeIt& e, Node v) const { 
+      e=OutEdgeIt(*this, v); return e; }
+    InEdgeIt& /*getF*/first(InEdgeIt& e, Node v) const { 
+      e=InEdgeIt(*this, v); return e; }
+    SymEdgeIt& /*getF*/first(SymEdgeIt& e, Node v) const { 
+      e=SymEdgeIt(*this, v); return e; }
+    //void getTail(Node& n, const Edge& e) const { n=tail(e); }
+    //void getHead(Node& n, const Edge& e) const { n=head(e); }
+
+    //void getANode(Node& n, const OutEdgeIt& e) const { n=e.aNode(); }
+    //void getANode(Node& n, const InEdgeIt& e) const { n=e.aNode(); }
+    //void getANode(Node& n, const SymEdgeIt& e) const { n=e.aNode(); }
+    //void getBNode(Node& n, const OutEdgeIt& e) const { n=e.bNode(); }
+    //void getBNode(Node& n, const InEdgeIt& e) const { n=e.bNode(); }
+    //void getBNode(Node& n, const SymEdgeIt& e) const { n=e.bNode(); }
+    //void get_invalid(Node& n) { n=Node(); }
+    //void get_invalid(Edge& e) { e=Edge(); }
+    //void get_invalid(OutEdgeIt& e) { e=OutEdgeIt(); }
+    //void get_invalid(InEdgeIt& e) { e=InEdgeIt(); }
+    //void get_invalid(SymEdgeIt& e) { e=SymEdgeIt(); }
+
+    template< typename It >
+    It first() const { 
+      It e;
+      /*getF*/first(e);
+      return e; 
+    }
+
+    template< typename It >
+    It first(Node v) const { 
+      It e;
+      /*getF*/first(e, v);
+      return e; 
+    }
+
+    bool valid(Node n) const { return n.valid(); }
+    bool valid(Edge e) const { return e.valid(); }
+    
+//    template <typename It> It getNext(It it) const { 
+//      It tmp(it); next(tmp); return tmp; }
+//     NodeIt& next(NodeIt& it) const { return ++it; }
+//     EdgeIt& next(EdgeIt& it) const { return ++it; }
+//     OutEdgeIt& next(OutEdgeIt& it) const { return ++it; }
+//     InEdgeIt& next(InEdgeIt& it) const { return ++it; }
+//     SymEdgeIt& next(SymEdgeIt& it) const { return ++it; }
+//    template <typename It> It& next(It& it) const { return ++it; }
+    template <typename It> It& next(It& it) const { ++it; return it; }
+   
+
+    /* for getting id's of graph objects */
+    /* these are important for the implementation of property vectors */
+
+    int id(Node v) const { return v.node->id; }
+    int id(Edge e) const { return e.edge->id; }
+
+    /* adding nodes and edges */
+
+    Node addNode() { return Node(_add_node()); }
+    Edge addEdge(Node u, Node v) {
+      return Edge(_add_edge(u.node, v.node)); 
+    }
+
+    void erase(Node i) { 
+      while (first<OutEdgeIt>(i).valid()) erase(first<OutEdgeIt>(i));
+      while (first<InEdgeIt>(i).valid()) erase(first<InEdgeIt>(i));
+      _delete_node(i.node); 
+    }
+  
+    void erase(Edge e) { _delete_edge(e.edge); }
+
+    void clear() { 
+      while (first<NodeIt>().valid()) erase(first<NodeIt>());
+    }
+
+    void setTail(Edge e, Node tail) {
+      _set_tail(e.edge, tail.node); 
+    }
+
+    void setHead(Edge e, Node head) {
+      _set_head(e.edge, head.node); 
+    }
+
+    /* stream operations, for testing purpose */
+
+    friend std::ostream& operator<<(std::ostream& os, const Node& i) { 
+      os << i.node->id; return os; 
+    }
+    friend std::ostream& operator<<(std::ostream& os, const Edge& i) { 
+      os << "(" << i.edge->_tail->id << "--" << i.edge->id << "->" << i.edge->_head->id << ")"; 
+      return os; 
+    }
+
+    class Node {
+      friend class ListGraph;
+      template <typename T> friend class NodeMap;
+
+      friend class Edge;
+      friend class OutEdgeIt;
+      friend class InEdgeIt;
+      friend class SymEdgeIt;
+      //public:  //FIXME: It is required by op= of NodeIt
+    protected:
+      node_item* node;
+    protected:
+      friend int ListGraph::id(Node v) const; 
+    public:
+      Node() /*: node(0)*/ { }
+      Node(const Invalid&) : node(0) { }
+    protected:
+      Node(node_item* _node) : node(_node) { }
+      bool valid() const { return (node); }
+    public:
+      //void makeInvalid() { node=0; }
+      friend bool operator==(Node u, Node v) { return v.node==u.node; } 
+      friend bool operator!=(Node u, Node v) { return v.node!=u.node; } 
+      friend std::ostream& operator<<(std::ostream& os, const Node& i);
+    };
+    
+    class NodeIt : public Node {
+      friend class ListGraph;
+      //protected:
+    public: //for everybody but marci
+      NodeIt(const ListGraph& G) : Node(G._first_node) { }
+    public:
+      NodeIt() : Node() { }
+      NodeIt(const Invalid& i) : Node(i) { }
+    protected:
+      NodeIt(node_item* v) : Node(v) { }
+      NodeIt& operator++() { node=node->_next_node; return *this; }
+      //FIXME::
+      //      NodeIt& operator=(const Node& e)
+      //      { node=e.node; return *this; }
+    };
+
+    class Edge {
+      friend class ListGraph;
+      template <typename T> friend class EdgeMap;
+      
+      friend class Node;
+      friend class NodeIt;
+    protected:
+      edge_item* edge;
+      friend int ListGraph::id(Edge e) const;
+    public:
+      Edge() /*: edge(0)*/ { }
+      Edge(const Invalid&) : edge(0) { }
+      //Edge() { }
+    protected:
+      Edge(edge_item* _edge) : edge(_edge) { }
+      bool valid() const { return (edge); }
+    public:
+      //void makeInvalid() { edge=0; }
+      friend bool operator==(Edge u, Edge v) { return v.edge==u.edge; } 
+      friend bool operator!=(Edge u, Edge v) { return v.edge!=u.edge; } 
+    protected:
+      Node tailNode() const { return Node(edge->_tail); }
+      Node headNode() const { return Node(edge->_head); }
+    public:
+      friend std::ostream& operator<<(std::ostream& os, const Edge& i);
+    };
+    
+    class EdgeIt : public Edge {
+      friend class ListGraph;
+      //protected: 
+    public: //for alpar
+      EdgeIt(const ListGraph& G) {
+	node_item* v=G._first_node;
+	if (v) edge=v->_first_out_edge; else edge=0;
+	while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; }
+      }
+    public:
+      EdgeIt() : Edge() { }
+      EdgeIt(const Invalid& i) : Edge(i) { }
+    protected:
+      EdgeIt(edge_item* _e) : Edge(_e) { }
+      EdgeIt& operator++() { 
+	node_item* v=edge->_tail;
+	edge=edge->_next_out; 
+	while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; }
+	return *this;
+      }
+    };
+    
+    class OutEdgeIt : public Edge {
+      friend class ListGraph;
+      //node_item* v;
+      //protected: 
+    protected: //for alpar
+      OutEdgeIt(const Node& _v) /*: v(_v.node)*/ { edge=_v.node->_first_out_edge; }
+    public:
+      OutEdgeIt() : Edge()/*, v(0)*/ { }
+      OutEdgeIt(const Invalid& i) : Edge(i) { }
+      OutEdgeIt(const ListGraph&, Node _v) /*: v(_v.node)*/ { edge=_v.node->_first_out_edge; }
+    protected:
+      OutEdgeIt& operator++() { edge=edge->_next_out; return *this; }
+    protected:
+      Node aNode() const { return Node(edge->_tail); }
+      Node bNode() const { return Node(edge->_head); }
+    };
+    
+    class InEdgeIt : public Edge {
+      friend class ListGraph;
+      //node_item* v;
+      //protected:
+    protected: //for alpar
+      InEdgeIt(const Node& _v) /*: v(_v.node)*/ { edge=_v.node->_first_in_edge; }
+    public:
+      InEdgeIt() : Edge()/*, v(0)*/ { }
+      InEdgeIt(const Invalid& i) : Edge(i) { }
+      InEdgeIt(const ListGraph&, Node _v) /*: v(_v.node)*/ { edge=_v.node->_first_in_edge; }
+    protected:
+      InEdgeIt& operator++() { edge=edge->_next_in; return *this; }
+    protected:
+      Node aNode() const { return Node(edge->_head); }
+      Node bNode() const { return Node(edge->_tail); }
+    };
+
+    class SymEdgeIt : public Edge {
+      friend class ListGraph;
+      bool out_or_in; //1 iff out, 0 iff in
+      //node_item* v;
+      //protected:
+    public: //for alpar
+      SymEdgeIt(const Node& _v) /*: v(_v.node)*/ { 
+	out_or_in=1;
+	edge=_v.node->_first_out_edge; 
+	if (!edge) { edge=_v.node->_first_in_edge; out_or_in=0; }
+      }
+    public:
+      SymEdgeIt() : Edge() /*, v(0)*/ { }
+      SymEdgeIt(const Invalid& i) : Edge(i) { }
+      SymEdgeIt(const ListGraph&, Node _v) /*: v(_v.node)*/ { 
+	out_or_in=1;
+	edge=_v.node->_first_out_edge; 
+	if (!edge) { edge=_v.node->_first_in_edge; out_or_in=0; }
+      }
+    protected:
+      SymEdgeIt& operator++() { 
+	if (out_or_in) { 
+	  node_item* v=edge->_tail;
+	  edge=edge->_next_out; 
+	  if (!edge) { out_or_in=0; edge=v->_first_in_edge; }
+	} else {
+	  edge=edge->_next_in; 
+	}
+	return *this;
+      }
+    protected:
+      Node aNode() const { 
+	return (out_or_in) ? Node(edge->_tail) : Node(edge->_head); }
+      Node bNode() const { 
+	return (out_or_in) ? Node(edge->_head) : Node(edge->_tail); }
+    };
+
+  };
+
+//   template< typename T >
+//   T ListGraph::first() const { 
+//     std::cerr << "Invalid use of template<typemane T> T ListGraph::first<T>();" << std::endl; 
+//     return T(); 
+//   }
+
+//   template<>
+//   ListGraph::NodeIt ListGraph::first<ListGraph::NodeIt>() const { 
+//     return firstNode(); 
+//   }
+
+//   template<>
+//   ListGraph::EdgeIt ListGraph::first<ListGraph::EdgeIt>() const { 
+//     return firstEdge(); 
+//   }
+
+//   template< typename T >
+//   T ListGraph::first(ListGraph::Node v) const {
+//     std::cerr << "Invalid use of template<typemane T> T ListGraph::first<T>(ListGRaph::Node);" << std::endl; 
+//     return T(); 
+//   } 
+
+//   template<>
+//   ListGraph::OutEdgeIt ListGraph::first<ListGraph::OutEdgeIt>(const ListGraph::Node v) const { 
+//     return firstOutEdge(v); 
+//   }
+
+//   template<>
+//   ListGraph::InEdgeIt ListGraph::first<ListGraph::InEdgeIt>(const ListGraph::Node v) const { 
+//     return firstInEdge(v); 
+//   }
+
+//   template<>
+//   ListGraph::SymEdgeIt ListGraph::first<ListGraph::SymEdgeIt>(const ListGraph::Node v) const { 
+//     return firstSymEdge(v); 
+//   }
+
+
+} //namespace hugo
+
+#endif //HUGO_LIST_GRAPH_H

Added: hugo/trunk/src/work/marci/experiment/makefile
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/marci/experiment/makefile	Sat Apr  3 19:26:46 2004
@@ -0,0 +1,35 @@
+INCLUDEDIRS ?= -I. -I../../../include -I..
+CXXFLAGS = -g -O3 -W -Wall $(INCLUDEDIRS) -ansi -pedantic
+
+BINARIES ?= iterator_bfs_demo iterator_bfs_demo_1 edmonds_karp_demo edmonds_karp_demo_1
+
+# Hat, ez elismerem, hogy nagyon ronda, de mukodik minden altalam
+# ismert rendszeren :-)  (Misi)
+CXX := $(shell type -p g++-3.3 || type -p g++-3.2 || type -p g++-3.0 || type -p g++-3 || echo g++)
+CC := $(CXX)
+
+
+all: $(BINARIES)
+
+################
+# Minden binarishoz egy sor, felsorolva, hogy mely object file-okbol
+# all elo.
+# Kiveve ha siman file.cc -> file  esetrol van szo, amikor is nem kell
+# irni semmit.
+
+#proba: proba.o seged.o
+
+################
+
+
+.depend dep depend:
+	-$(CXX) $(INCLUDEDIRS) -M $(BINARIES:=.cc) > .depend #2>/dev/null
+#	-$(CXX) $(CXXFLAGS) -M *.cc > .depend
+
+makefile: .depend
+sinclude .depend
+
+clean:
+	$(RM) *.o $(BINARIES) .depend
+
+.PHONY: all clean dep depend



More information about the Lemon-commits mailing list