Index: lemon/dimacs.h
===================================================================
--- lemon/dimacs.h	(revision 2391)
+++ lemon/dimacs.h	(revision 2413)
@@ -28,9 +28,8 @@
 /// \ingroup dimacs_group
 /// \file
-/// \brief Dimacs file format reader.
+/// \brief DIMACS file format reader.
 
 namespace lemon {
 
-  ///
   ///@defgroup dimacs_group DIMACS format
   ///\brief Read and write files in DIMACS format
@@ -42,79 +41,68 @@
   /// \addtogroup dimacs_group
   /// @{
-
-  /// Dimacs min cost flow reader function.
-
-  /// This function reads a min cost flow instance from dimacs format,
-  /// i.e. from dimacs files having a line starting with
-  ///\code
-  /// p "min"
-  ///\endcode
-  /// At the beginning \c g is cleared by \c g.clear(). The edge
-  /// capacities are written to \c capacity, \c s and \c t are set to
-  /// the source and the target nodes resp. and the cost of the edges
-  /// are written to \c cost.
-  ///
-  /// \author Marton Makai
-  template<typename Graph, typename CapacityMap, typename CostMap>
-  void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
-		  typename Graph::Node &s, typename Graph::Node &t, 
-		  CostMap& cost) {
+  
+  /// DIMACS min cost flow reader function.
+  ///
+  /// This function reads a min cost flow instance from DIMACS format,
+  /// i.e. from DIMACS files having a line starting with
+  /// \code
+  ///   p min
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear(). The supply 
+  /// amount of the nodes are written to \c supply (signed). The 
+  /// lower bounds, capacities and costs of the edges are written to 
+  /// \c lower, \c capacity and \c cost.
+  ///
+  /// \author Marton Makai and Peter Kovacs
+  template <typename Graph, typename SupplyMap, 
+    typename CapacityMap, typename CostMap>
+  void readDimacs( std::istream& is,
+		   Graph &g,
+		   SupplyMap& supply, 
+		   CapacityMap& lower, 
+		   CapacityMap& capacity, 
+		   CostMap& cost )
+  {
     g.clear();
-    typename CapacityMap::Value _cap;
-    typename CostMap::Value _cost;
-    char d;
-    std::string problem;
+    std::vector<typename Graph::Node> nodes;
+    typename Graph::Edge e;
+    std::string problem, str;
     char c;
+    int n, m; 
     int i, j;
-    std::string str;
-    int n, m; 
-    typename Graph::Edge e;
-    std::vector<typename Graph::Node> nodes;
-    while (is>>c) {
+    typename SupplyMap::Value sup;
+    typename CapacityMap::Value low;
+    typename CapacityMap::Value cap;
+    typename CostMap::Value co;
+    while (is >> c) {
       switch (c) {
-      case 'c': //comment
-	getline(is, str);
-	break;
-      case 'p': //problem definition
+      case 'c': // comment line
+	getline(is, str);
+	break;
+      case 'p': // problem definition line
 	is >> problem >> n >> m;
 	getline(is, str);
-	nodes.resize(n+1);
-	for (int k=1; k<=n; ++k) nodes[k]=g.addNode();
-	break;
-      case 'n': //node definition
-	if (problem=="sp") { //shortest path problem
-	  is >> i;
-	  getline(is, str);
-	  s=nodes[i];
-	}
-	if (problem=="max" || problem=="min") { //((max) or (min cost)) flow problem
-	  is >> i >> d;
-	  getline(is, str);
-	  if (d=='s') s=nodes[i];
-	  if (d=='t') t=nodes[i];
-	}
-	break;
-      case 'a':
-	if ( problem == "max" || problem == "sp") {
-	  is >> i >> j >> _cap;
-	  getline(is, str);
-	  e=g.addEdge(nodes[i], nodes[j]);
-	  //capacity.update();
-	  capacity.set(e, _cap);
-	} else {
-	  if ( problem == "min" ) {
-	    is >> i >> j >> _cap >> _cost;
-	    getline(is, str);
-	    e=g.addEdge(nodes[i], nodes[j]);
-	    //capacity.update();
-	    capacity.set(e, _cap);
-	    //cost.update();
-	    cost.set(e, _cost);
-	  } else {
-	    is >> i >> j;
-	    getline(is, str);
-	    g.addEdge(nodes[i], nodes[j]);
-	  }
-	}
+	if (problem != "min") return;
+	nodes.resize(n + 1);
+	for (int k = 1; k <= n; ++k) {
+	  nodes[k] = g.addNode();
+	  supply[nodes[k]] = 0;
+	}
+	break;
+      case 'n': // node definition line
+	is >> i >> sup;
+	getline(is, str);
+	supply.set(nodes[i], sup);
+	break;
+      case 'a': // edge (arc) definition line
+	is >> i >> j >> low >> cap >> co;
+	getline(is, str);
+	e = g.addEdge(nodes[i], nodes[j]);
+	lower.set(e, low);
+	if (cap >= 0)
+	  capacity.set(e, cap);
+	else
+	  capacity.set(e, -1);
+	cost.set(e, co);
 	break;
       }
@@ -122,14 +110,13 @@
   }
 
-
-  /// Dimacs max flow reader function.
-
-  /// This function reads a max flow instance from dimacs format,
-  /// i.e. from dimacs files having a line starting with
-  ///\code
-  /// p "max"
-  ///\endcode
-  ///At the beginning \c g is cleared by \c g.clear(). The
-  /// edge capacities are written to \c capacity and \c s and \c t are
+  /// DIMACS max flow reader function.
+  ///
+  /// This function reads a max flow instance from DIMACS format,
+  /// i.e. from DIMACS files having a line starting with
+  /// \code
+  ///   p max
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear(). The edge 
+  /// capacities are written to \c capacity and \c s and \c t are
   /// set to the source and the target nodes.
   ///
@@ -138,16 +125,61 @@
   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
 		  typename Graph::Node &s, typename Graph::Node &t) {
-    NullMap<typename Graph::Edge, int> n;
-    readDimacs(is, g, capacity, s, t, n);
-  }
-
-
-  /// Dimacs shortest path reader function.
-
-  /// This function reads a shortest path instance from dimacs format,
-  /// i.e. from dimacs files having a line starting with
-  ///\code
-  /// p "sp"
-  ///\endcode
+    g.clear();
+    std::vector<typename Graph::Node> nodes;
+    typename Graph::Edge e;
+    std::string problem;
+    char c, d;
+    int n, m; 
+    int i, j;
+    typename CapacityMap::Value _cap;
+    std::string str;
+    while (is >> c) {
+      switch (c) {
+      case 'c': // comment line
+	getline(is, str);
+	break;
+      case 'p': // problem definition line
+	is >> problem >> n >> m;
+	getline(is, str);
+	nodes.resize(n + 1);
+	for (int k = 1; k <= n; ++k)
+	  nodes[k] = g.addNode();
+	break;
+      case 'n': // node definition line
+	if (problem == "sp") { // shortest path problem
+	  is >> i;
+	  getline(is, str);
+	  s = nodes[i];
+	}
+	if (problem == "max") { // max flow problem
+	  is >> i >> d;
+	  getline(is, str);
+	  if (d == 's') s = nodes[i];
+	  if (d == 't') t = nodes[i];
+	}
+	break;
+      case 'a': // edge (arc) definition line
+	if (problem == "max" || problem == "sp") {
+	  is >> i >> j >> _cap;
+	  getline(is, str);
+	  e = g.addEdge(nodes[i], nodes[j]);
+	  capacity.set(e, _cap);
+	} else {
+	  is >> i >> j;
+	  getline(is, str);
+	  g.addEdge(nodes[i], nodes[j]);
+	}
+	break;
+      }
+    }
+  }
+
+  /// DIMACS shortest path reader function.
+  ///
+  /// This function reads a shortest path instance from DIMACS format,
+  /// i.e. from DIMACS files having a line starting with
+  /// \code
+  ///   p sp
+  /// \endcode
   /// At the beginning \c g is cleared by \c g.clear(). The edge
   /// capacities are written to \c capacity and \c s is set to the
@@ -158,13 +190,11 @@
   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity, 
 		  typename Graph::Node &s) {
-    NullMap<typename Graph::Edge, int> n;
-    readDimacs(is, g, capacity, s, s, n);
-  }
-
-
-  /// Dimacs capacitated graph reader function.
-
+    readDimacs(is, g, capacity, s, s);
+  }
+
+  /// DIMACS capacitated graph reader function.
+  ///
   /// This function reads an edge capacitated graph instance from
-  /// dimacs format.  At the beginning \c g is cleared by \c g.clear()
+  /// DIMACS format. At the beginning \c g is cleared by \c g.clear()
   /// and the edge capacities are written to \c capacity.
   ///
@@ -173,19 +203,16 @@
   void readDimacs(std::istream& is, Graph &g, CapacityMap& capacity) {
     typename Graph::Node u;
-    NullMap<typename Graph::Edge, int> n;
-    readDimacs(is, g, capacity, u, u, n);
-  }
-
-
-  /// Dimacs plain graph reader function.
-
+    readDimacs(is, g, capacity, u, u);
+  }
+
+  /// DIMACS plain graph reader function.
+  ///
   /// This function reads a graph without any designated nodes and
-  /// maps from dimacs format, i.e. from dimacs files having a line
+  /// maps from DIMACS format, i.e. from DIMACS files having a line
   /// starting with
-  ///\code
-  /// p "mat"
-  ///\endcode
-  /// At the beginning \c g is cleared
-  /// by \c g.clear().
+  /// \code
+  ///   p mat
+  /// \endcode
+  /// At the beginning \c g is cleared by \c g.clear().
   ///
   /// \author Marton Makai
@@ -194,11 +221,17 @@
     typename Graph::Node u;
     NullMap<typename Graph::Edge, int> n;
-    readDimacs(is, g, n, u, u, n);
+    readDimacs(is, g, n, u, u);
   }
   
-
-
-  
-  /// write matching problem
+  /// DIMACS plain graph writer function.
+  ///
+  /// This function writes a graph without any designated nodes and
+  /// maps into DIMACS format, i.e. into DIMACS file having a line 
+  /// starting with
+  /// \code
+  ///   p mat
+  /// \endcode
+  ///
+  /// \author Marton Makai
   template<typename Graph>
   void writeDimacs(std::ostream& os, const Graph &g) {
@@ -206,20 +239,16 @@
     typedef typename Graph::EdgeIt EdgeIt;  
     
+    os << "c matching problem" << std::endl;
+    os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
+
     typename Graph::template NodeMap<int> nodes(g);
-
-    os << "c matching problem" << std::endl;
-
-    int i=1;
-    for(NodeIt v(g); v!=INVALID; ++v) {
+    int i = 1;
+    for(NodeIt v(g); v != INVALID; ++v) {
       nodes.set(v, i);
       ++i;
     }    
-    
-    os << "p mat " << g.nodeNum() << " " << g.edgeNum() << std::endl;
-
-    for(EdgeIt e(g); e!=INVALID; ++e) {
+    for(EdgeIt e(g); e != INVALID; ++e) {
       os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)] << std::endl; 
     }
-
   }
 
