You need to figure out which vertices to include in the subgraph. You can do this by walking back from the bottom vertices you selected to the root node.
//Create graph
Graph<String, DefaultEdge> dag = new SimpleDirectedGraph<>(DefaultEdge.class);
Graphs.addAllVertices(dag, Arrays.asList("A","B","C","D","E","G"));
dag.addEdge("A","B");
dag.addEdge("A","C");
dag.addEdge("B","D");
dag.addEdge("B","E");
dag.addEdge("D","G");
NeighborCache<String, DefaultEdge> neighborCache = new NeighborCache<>(dag);
//Define inputs
Set<String> blockers = Set.of("D", "E");
//Figure out which vertices are in the subgraph
Queue<String> queue=new LinkedList<>();
queue.addAll(blockers);
Set<String> subgraphVertices = new HashSet<>();
while(!queue.isEmpty()){
String vertex = queue.poll();
subgraphVertices.add(vertex);
queue.addAll(neighborCache.predecessorsOf(vertex));
}
//Create subgraph
Graph<String,DefaultEdge> subDag = new AsSubgraph<>(dag, subgraphVertices);
System.out.println(subDag);
If desired, you could include some performance improvements in the above code, since some vertices get added multiple times to the queue. As per example, when you walk back from vertex D to the root node A, you will encounter vertex B. Similarly, when you walk back from E, you encounter B again. There's no need to re-visit B.