private boolean hasAugmentingPath(FlowNetwork G, int s, int t) {
    edgeTo = new FlowEdge[G.V()];
    marked = new boolean[G.V()];
    
    Queue<Integer> q = new LinkedList<Integer>();
    q.add(s);
    marked[s] = true;
    
    while (!q.isEmpty()) {
      int v = q.remove();
     
      
      for (FlowEdge e : G.adj(v)) {
        // backward edge of v -> w is not empty
        int w = e.other(v);
        
        // path v->w is in the residual network?
        // => forward edge of v->w is not full
        if (e.residualCapacityTo(w) > 0 && !marked[w]) {
          edgeTo[w] = e;
          marked[w] = true;
          q.add(w);
        }
      }
    }
    
    return marked[t];
  }