private boolean applyAfterDirectedEdgeWeight(Update u) {
    DirectedWeightedEdge e = (DirectedWeightedEdge) ((EdgeWeight) u).getEdge();
    IntWeight eWeight = (IntWeight) e.getWeight();

    for (IElement ie : g.getNodes()) {
      DirectedNode s = (DirectedNode) ie;
      HashMap<Node, Node> parent = parents.get(s);
      HashMap<Node, Integer> height = heights.get(s);

      DirectedNode src = e.getSrc();
      DirectedNode dst = e.getDst();

      if (height.get(src) + (int) eWeight.getWeight() == height.get(dst)) {
        continue;
      }

      if (height.get(src) + (int) eWeight.getWeight() > height.get(dst)
          || height.get(src) + (int) eWeight.getWeight() < 0) {
        if (parent.containsKey(dst) && parent.get(dst).equals(src)) {
          directedDelete(s, e);
        }
      } else {
        directedAdd(e, s);
      }
      apsp.truncate();
    }
    return true;
  }
  private boolean directedAdd(DirectedWeightedEdge e, DirectedNode s) {
    HashMap<Node, Node> parent = parents.get(s);
    HashMap<Node, Integer> height = heights.get(s);
    IntWeight eWeight = (IntWeight) e.getWeight();

    DirectedNode src = e.getSrc();
    DirectedNode dst = e.getDst();
    if (height.get(src) + (int) eWeight.getWeight() >= height.get(dst)
        || height.get(src) + (int) eWeight.getWeight() < 0) {
      return true;
    }
    if (height.get(dst) != Integer.MAX_VALUE) apsp.decr(height.get(dst));
    height.put(dst, height.get(src) + (int) eWeight.getWeight());
    apsp.incr(height.get(src) + (int) eWeight.getWeight());
    parent.put(dst, src);
    PriorityQueue<QueueElement<DirectedNode>> q = new PriorityQueue<QueueElement<DirectedNode>>();
    QueueElement<DirectedNode> queueElement = new QueueElement<DirectedNode>(dst, height.get(dst));
    q.add(queueElement);
    while (!q.isEmpty()) {
      QueueElement<DirectedNode> c = q.poll();
      DirectedNode current = c.e;

      if (height.get(current) == Integer.MAX_VALUE) {
        break;
      }

      for (IElement iEdge : current.getOutgoingEdges()) {
        DirectedWeightedEdge d = (DirectedWeightedEdge) iEdge;
        DirectedNode neighbor = d.getDst();
        IntWeight dWeight = (IntWeight) d.getWeight();

        int alt = height.get(current) + (int) dWeight.getWeight();

        if (alt < height.get(neighbor)) {
          if (height.get(neighbor) != Integer.MAX_VALUE) apsp.decr(height.get(neighbor));
          apsp.incr(alt);
          height.put(neighbor, alt);
          parent.put(neighbor, current);
          QueueElement<DirectedNode> temp =
              new QueueElement<DirectedNode>(neighbor, height.get(neighbor));
          if (q.contains(temp)) {
            q.remove(temp);
          }
          q.add(temp);
        }
      }
    }
    return true;
  }
  private void directedDelete(DirectedNode r, DirectedEdge e) {
    HashMap<Node, Node> parent = this.parents.get(r);
    HashMap<Node, Integer> height = this.heights.get(r);
    DirectedNode src = e.getSrc();
    DirectedNode dst = e.getDst();

    // if the source or dst or edge is not in tree do nothing
    if (height.get(src) == Integer.MAX_VALUE
        || height.get(dst) == Integer.MAX_VALUE
        || dst.equals(r)
        || !parent.get(dst).equals(src)) {
      return;
    }

    // Queues and data structure for tree change
    HashSet<DirectedNode> uncertain = new HashSet<DirectedNode>();
    HashSet<DirectedNode> changed = new HashSet<DirectedNode>();

    PriorityQueue<QueueElement<DirectedNode>> q = new PriorityQueue<QueueElement<DirectedNode>>();

    q.add(new QueueElement<DirectedNode>(dst, height.get(dst)));

    uncertain.add(dst);
    parent.remove(dst);

    while (!q.isEmpty()) {
      QueueElement<DirectedNode> qE = q.poll();
      DirectedNode w = qE.e;

      int key = qE.distance;

      // find the new shortest path
      int dist = Integer.MAX_VALUE;

      ArrayList<DirectedNode> minSettled = new ArrayList<DirectedNode>();
      ArrayList<DirectedNode> min = new ArrayList<DirectedNode>();
      for (IElement iEgde : w.getIncomingEdges()) {
        DirectedWeightedEdge edge = (DirectedWeightedEdge) iEgde;
        IntWeight eWeight = (IntWeight) edge.getWeight();
        DirectedNode z = edge.getSrc();

        if (changed.contains(z) || height.get(z) == Integer.MAX_VALUE) {
          continue;
        }
        if (height.get(z) + (int) eWeight.getWeight() < dist) {
          min.clear();
          minSettled.clear();
          min.add(z);
          if (!uncertain.contains(z)) minSettled.add(z);
          dist = height.get(z) + (int) eWeight.getWeight();
          continue;
        }
        if (height.get(z) + (int) eWeight.getWeight() == dist) {
          min.add(z);
          if (!uncertain.contains(z)) minSettled.add(z);
          continue;
        }
      }

      boolean noPossibleNeighbour =
          (key >= breakLoop && dist > breakLoop)
              || (min.isEmpty() && (!uncertain.contains(w) || (key == dist)));

      // no neighbour found
      if (noPossibleNeighbour) {
        if (height.get(w) != Integer.MAX_VALUE) apsp.decr(height.get(w));
        height.put(w, Integer.MAX_VALUE);
        parent.remove(w);
        continue;
      }
      if (uncertain.contains(w)) {
        if (key == dist) {
          if (minSettled.isEmpty()) {
            parent.put(w, min.get(0));
          } else {
            parent.put(w, minSettled.get(0));
          }
          if (height.get(w) != Integer.MAX_VALUE) apsp.decr(height.get(w));
          apsp.incr(dist);
          height.put(w, dist);
          for (IElement iEgde : w.getOutgoingEdges()) {
            DirectedWeightedEdge edge = (DirectedWeightedEdge) iEgde;
            IntWeight iEdgeWeight = (IntWeight) edge.getWeight();

            DirectedNode z = edge.getDst();

            if (height.get(z) > dist + (int) iEdgeWeight.getWeight()) {
              q.remove(new QueueElement<DirectedNode>(z, dist + (int) iEdgeWeight.getWeight()));
              q.add(new QueueElement<DirectedNode>(z, dist + (int) iEdgeWeight.getWeight()));
            }
          }
        } else {
          changed.add(w);

          q.add(new QueueElement<DirectedNode>(w, dist));
          uncertain.remove(w);
          for (IElement iEgde : w.getOutgoingEdges()) {
            DirectedEdge edge = (DirectedEdge) iEgde;

            DirectedNode z = edge.getDst();

            if (parent.get(z) == w) {
              parent.remove(z);
              uncertain.add(z);
              q.add(new QueueElement<DirectedNode>(z, height.get(z)));
            }
          }
        }
        continue;
      }
      if (dist > key) {
        q.add(new QueueElement<DirectedNode>(w, dist));

        continue;
      }
      if (minSettled.isEmpty()) {
        parent.put(w, min.get(0));
      } else {
        parent.put(w, minSettled.get(0));
      }

      changed.remove(w);
      if (height.get(w) != Integer.MAX_VALUE) apsp.decr(height.get(w));
      apsp.incr(dist);
      height.put(w, dist);
      for (IElement iEgde : w.getOutgoingEdges()) {
        DirectedWeightedEdge edge = (DirectedWeightedEdge) iEgde;
        IntWeight eWeight = (IntWeight) edge.getWeight();

        DirectedNode z = edge.getDst();

        if (height.get(z) > dist + (int) eWeight.getWeight()) {
          q.remove(new QueueElement<DirectedNode>(z, dist + (int) eWeight.getWeight()));
          q.add(new QueueElement<DirectedNode>(z, dist + (int) eWeight.getWeight()));
        }
      }
    }
  }