Location: LEMON/LEMON-official/lemon/dimacs.h - annotation

Load file history
gravatar
kpeter (Peter Kovacs)
Doc improvements in GomoryHu (#66) And make init() and start() private + bug fix in the test file.
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r463:88ed40ad0d4f
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r403:0a3ec097a76c
 r402:24a2c6ee6cb0
 r403:0a3ec097a76c
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r403:0a3ec097a76c
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r403:0a3ec097a76c
 r400:50d96f2166d7
 r403:0a3ec097a76c
 r403:0a3ec097a76c
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r403:0a3ec097a76c
 r402:24a2c6ee6cb0
 r403:0a3ec097a76c
 r403:0a3ec097a76c
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r403:0a3ec097a76c
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r403:0a3ec097a76c
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r401:9d1faab5e0f1
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r401:9d1faab5e0f1
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r400:50d96f2166d7
 r572:635a8375227d
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r572:635a8375227d
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r402:24a2c6ee6cb0
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r463:88ed40ad0d4f
 r402:24a2c6ee6cb0
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
 r400:50d96f2166d7
/* -*- mode: C++; indent-tabs-mode: nil; -*-
 *
 * This file is a part of LEMON, a generic C++ optimization library.
 *
 * Copyright (C) 2003-2009
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
 *
 * Permission to use, modify and distribute this software is granted
 * provided that this copyright notice appears in all copies. For
 * precise terms see the accompanying LICENSE file.
 *
 * This software is provided "AS IS" with no warranty of any kind,
 * express or implied, and with no claim as to its suitability for any
 * purpose.
 *
 */

#ifndef LEMON_DIMACS_H
#define LEMON_DIMACS_H

#include <iostream>
#include <string>
#include <vector>
#include <lemon/maps.h>
#include <lemon/error.h>

/// \ingroup dimacs_group
/// \file
/// \brief DIMACS file format reader.

namespace lemon {

  /// \addtogroup dimacs_group
  /// @{

  /// DIMACS file type descriptor.
  struct DimacsDescriptor
  {
    ///File type enum
    enum Type
      {
        NONE, MIN, MAX, SP, MAT
      };
    ///The file type
    Type type;
    ///The number of nodes in the graph
    int nodeNum;
    ///The number of edges in the graph
    int edgeNum;
    int lineShift;
    /// Constructor. Sets the type to NONE.
    DimacsDescriptor() : type(NONE) {}
  };

  ///Discover the type of a DIMACS file

  ///It starts seeking the begining of the file for the problem type
  ///and size info. The found data is returned in a special struct
  ///that can be evaluated and passed to the appropriate reader
  ///function.
  DimacsDescriptor dimacsType(std::istream& is)
  {
    DimacsDescriptor r;
    std::string problem,str;
    char c;
    r.lineShift=0;
    while (is >> c)
      switch(c)
        {
        case 'p':
          if(is >> problem >> r.nodeNum >> r.edgeNum)
            {
              getline(is, str);
              r.lineShift++;
              if(problem=="min") r.type=DimacsDescriptor::MIN;
              else if(problem=="max") r.type=DimacsDescriptor::MAX;
              else if(problem=="sp") r.type=DimacsDescriptor::SP;
              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
              else throw FormatError("Unknown problem type");
              return r;
            }
          else
            {
              throw FormatError("Missing or wrong problem type declaration.");
            }
          break;
        case 'c':
          getline(is, str);
          r.lineShift++;
          break;
        default:
          throw FormatError("Unknown DIMACS declaration.");
        }
    throw FormatError("Missing problem type declaration.");
  }



  /// DIMACS minimum cost flow reader function.
  ///
  /// This function reads a minimum cost flow instance from DIMACS format,
  /// i.e. from a DIMACS file 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 arcs are written to
  /// \c lower, \c capacity and \c cost.
  ///
  /// If the file type was previously evaluated by dimacsType(), then
  /// the descriptor struct should be given by the \c dest parameter.
  template <typename Digraph, typename LowerMap,
            typename CapacityMap, typename CostMap,
            typename SupplyMap>
  void readDimacsMin(std::istream& is,
                     Digraph &g,
                     LowerMap& lower,
                     CapacityMap& capacity,
                     CostMap& cost,
                     SupplyMap& supply,
                     DimacsDescriptor desc=DimacsDescriptor())
  {
    g.clear();
    std::vector<typename Digraph::Node> nodes;
    typename Digraph::Arc e;
    std::string problem, str;
    char c;
    int i, j;
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    if(desc.type!=DimacsDescriptor::MIN)
      throw FormatError("Problem type mismatch");

    nodes.resize(desc.nodeNum + 1);
    for (int k = 1; k <= desc.nodeNum; ++k) {
      nodes[k] = g.addNode();
      supply.set(nodes[k], 0);
    }

    typename SupplyMap::Value sup;
    typename CapacityMap::Value low;
    typename CapacityMap::Value cap;
    typename CostMap::Value co;
    while (is >> c) {
      switch (c) {
      case 'c': // comment line
        getline(is, str);
        break;
      case 'n': // node definition line
        is >> i >> sup;
        getline(is, str);
        supply.set(nodes[i], sup);
        break;
      case 'a': // arc (arc) definition line
        is >> i >> j >> low >> cap >> co;
        getline(is, str);
        e = g.addArc(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;
      }
    }
  }

  template<typename Digraph, typename CapacityMap>
  void _readDimacs(std::istream& is,
                   Digraph &g,
                   CapacityMap& capacity,
                   typename Digraph::Node &s,
                   typename Digraph::Node &t,
                   DimacsDescriptor desc=DimacsDescriptor()) {
    g.clear();
    s=t=INVALID;
    std::vector<typename Digraph::Node> nodes;
    typename Digraph::Arc e;
    char c, d;
    int i, j;
    typename CapacityMap::Value _cap;
    std::string str;
    nodes.resize(desc.nodeNum + 1);
    for (int k = 1; k <= desc.nodeNum; ++k) {
      nodes[k] = g.addNode();
    }

    while (is >> c) {
      switch (c) {
      case 'c': // comment line
        getline(is, str);
        break;
      case 'n': // node definition line
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
          is >> i;
          getline(is, str);
          s = nodes[i];
        }
        if (desc.type==DimacsDescriptor::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': // arc (arc) definition line
        if (desc.type==DimacsDescriptor::SP ||
            desc.type==DimacsDescriptor::MAX) {
          is >> i >> j >> _cap;
          getline(is, str);
          e = g.addArc(nodes[i], nodes[j]);
          capacity.set(e, _cap);
        } else {
          is >> i >> j;
          getline(is, str);
          g.addArc(nodes[i], nodes[j]);
        }
        break;
      }
    }
  }

  /// DIMACS maximum flow reader function.
  ///
  /// This function reads a maximum flow instance from DIMACS format,
  /// i.e. from a DIMACS file having a line starting with
  /// \code
  ///   p max
  /// \endcode
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
  /// capacities are written to \c capacity and \c s and \c t are
  /// set to the source and the target nodes.
  ///
  /// If the file type was previously evaluated by dimacsType(), then
  /// the descriptor struct should be given by the \c dest parameter.
  template<typename Digraph, typename CapacityMap>
  void readDimacsMax(std::istream& is,
                     Digraph &g,
                     CapacityMap& capacity,
                     typename Digraph::Node &s,
                     typename Digraph::Node &t,
                     DimacsDescriptor desc=DimacsDescriptor()) {
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    if(desc.type!=DimacsDescriptor::MAX)
      throw FormatError("Problem type mismatch");
    _readDimacs(is,g,capacity,s,t,desc);
  }

  /// DIMACS shortest path reader function.
  ///
  /// This function reads a shortest path instance from DIMACS format,
  /// i.e. from a DIMACS file having a line starting with
  /// \code
  ///   p sp
  /// \endcode
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
  /// lengths are written to \c length and \c s is set to the
  /// source node.
  ///
  /// If the file type was previously evaluated by dimacsType(), then
  /// the descriptor struct should be given by the \c dest parameter.
  template<typename Digraph, typename LengthMap>
  void readDimacsSp(std::istream& is,
                    Digraph &g,
                    LengthMap& length,
                    typename Digraph::Node &s,
                    DimacsDescriptor desc=DimacsDescriptor()) {
    typename Digraph::Node t;
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    if(desc.type!=DimacsDescriptor::SP)
      throw FormatError("Problem type mismatch");
    _readDimacs(is, g, length, s, t,desc);
  }

  /// DIMACS capacitated digraph reader function.
  ///
  /// This function reads an arc capacitated digraph instance from
  /// DIMACS 'mat' or 'sp' format.
  /// At the beginning, \c g is cleared by \c g.clear()
  /// and the arc capacities/lengths are written to \c capacity.
  ///
  /// If the file type was previously evaluated by dimacsType(), then
  /// the descriptor struct should be given by the \c dest parameter.
  template<typename Digraph, typename CapacityMap>
  void readDimacsCap(std::istream& is,
                     Digraph &g,
                     CapacityMap& capacity,
                     DimacsDescriptor desc=DimacsDescriptor()) {
    typename Digraph::Node u,v;
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
      throw FormatError("Problem type mismatch");
    _readDimacs(is, g, capacity, u, v, desc);
  }

  template<typename Graph>
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
              dummy<0> = 0)
  {
    g.addEdge(s,t);
  }
  template<typename Graph>
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
              dummy<1> = 1)
  {
    g.addArc(s,t);
  }
  
  /// DIMACS plain (di)graph reader function.
  ///
  /// This function reads a (di)graph without any designated nodes and
  /// 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().
  ///
  /// If the file type was previously evaluated by dimacsType(), then
  /// the descriptor struct should be given by the \c dest parameter.
  template<typename Graph>
  void readDimacsMat(std::istream& is, Graph &g,
                     DimacsDescriptor desc=DimacsDescriptor())
  {
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
    if(desc.type!=DimacsDescriptor::MAT)
      throw FormatError("Problem type mismatch");

    g.clear();
    std::vector<typename Graph::Node> nodes;
    char c;
    int i, j;
    std::string str;
    nodes.resize(desc.nodeNum + 1);
    for (int k = 1; k <= desc.nodeNum; ++k) {
      nodes[k] = g.addNode();
    }
    
    while (is >> c) {
      switch (c) {
      case 'c': // comment line
        getline(is, str);
        break;
      case 'n': // node definition line
        break;
      case 'a': // arc (arc) definition line
        is >> i >> j;
        getline(is, str);
        _addArcEdge(g,nodes[i], nodes[j]);
        break;
      }
    }
  }

  /// DIMACS plain digraph writer function.
  ///
  /// This function writes a digraph without any designated nodes and
  /// maps into DIMACS format, i.e. into DIMACS file having a line
  /// starting with
  /// \code
  ///   p mat
  /// \endcode
  /// If \c comment is not empty, then it will be printed in the first line
  /// prefixed by 'c'.
  template<typename Digraph>
  void writeDimacsMat(std::ostream& os, const Digraph &g,
                      std::string comment="") {
    typedef typename Digraph::NodeIt NodeIt;
    typedef typename Digraph::ArcIt ArcIt;

    if(!comment.empty())
      os << "c " << comment << std::endl;
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;

    typename Digraph::template NodeMap<int> nodes(g);
    int i = 1;
    for(NodeIt v(g); v != INVALID; ++v) {
      nodes.set(v, i);
      ++i;
    }
    for(ArcIt e(g); e != INVALID; ++e) {
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
         << std::endl;
    }
  }

  /// @}

} //namespace lemon

#endif //LEMON_DIMACS_H