code: public Graph<T> reduce() {
          Builder<T> builder = new Builder<>();
          nodes.stream()
                  .forEach(u -> {
                      builder.addNode(u);
                      edges.get(u).stream()
                           .filter(v -> !pathExists(u, v, false))
                           .forEach(v -> builder.addEdge(u, v));
                  });
          return builder.build();
      }
docs: Returns a new Graph after transitive reduction