/**
   * Returns the distance of a vertex from the source.
   * @param v a vertex
   * @return the distance of v from the source
   * @throws InvalidQueryException if v has not been reached yet */
  public final int distance(Vertex v) throws InvalidQueryException {
    try {
      return ((Integer)v.get(DISTANCE)).intValue();
    }
    catch (InvalidAttributeException iae) {
      throw new InvalidQueryException(v+" has not been reached yet");
    }
  }
  /**
   * Returns the modified weight of edge e in the current residual
   * graph. It can be calculated on the fly because distance
   * information is only updated after every iteration of the
   * algorithm.
   * @param e Edge to find residual weight for
   * @return int residual weight of e */
  public final int residualWeight(Edge e) {
    // use the absolute value because if we traverse
    // the edge backwards, then w(v,u) = -w(u,v)
    return Math.abs( cost(e) +
		     distance(graph_.origin(e)) -
		     distance(graph_.destination(e)) );
  }
  /**
   * Determines whether edge e has null residual capacity when
   * traversed starting at endpoint v.
   * @param v Vertex from which edge is being considered
   * @param e Edge to check
   * @return boolean true if the edge is at capacity, false if not */
  public final boolean isAtCapacity(Vertex v, Edge e) {
    // forward edges are full when capacity == flow
    if( v == graph_.origin( e ) )
      return (capacity(e) == flow(e));
    // back edges are full when flow == 0
    else
      return (flow(e) == 0);
  }