diff --git a/Algoritmi_2/Laboratorio/Lab4/src/BFSAndDFSApp.java b/Algoritmi_2/Laboratorio/Lab4/src/BFSAndDFSApp.java
index b5b091d77a6cc5d6a167d09c80bfc68acdda60c7..a45fa3fe0e21187663c4eba0705cbc6177c8b899 100644
--- a/Algoritmi_2/Laboratorio/Lab4/src/BFSAndDFSApp.java
+++ b/Algoritmi_2/Laboratorio/Lab4/src/BFSAndDFSApp.java
@@ -106,7 +106,6 @@ class BFSAndDFSApp {
             throw new IllegalArgumentException("Impossibile usare hasDirCycle su un grafo non orientato");
         }
         for (int i = 0; i < myGraph.getOrder(); i++) {
-            System.out.println("pup!");
             fathers = new int[myGraph.getOrder()];
             Arrays.fill(fathers, -1);
             scoperti = new boolean[myGraph.getOrder()];
diff --git a/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java b/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java
index 05f8844b5972da762da47c16b2dc902ea4d9da18..13edc1bdbfebc8477fd189a63595a407d84ad9ee 100644
--- a/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java
+++ b/Algoritmi_2/Laboratorio/Lab5/Test/TestLab.java
@@ -65,4 +65,15 @@ class TestLab {
         DFS dfsTest3 = new DFS(gThreeNodes);
         Assertions.assertTrue(dfsTest3.topologicalOrder().indexOf(2) < dfsTest3.topologicalOrder().indexOf(0));
     }
+
+    @Test
+    void testTopologicalOrderDag() {
+        DirectedGraph dag = new DirectedGraph("4; 0 1; 0 2; 1 2; 1 3");
+        DFS dfsTest = new DFS(dag);
+        Assertions.assertTrue(dfsTest.topologicalOrderDag().indexOf(0) < dfsTest.topologicalOrder().indexOf(3));
+
+        DirectedGraph cyclicGraph = new DirectedGraph("3; 0 1; 1 2; 2 0");
+        DFS dfsCyclicTest = new DFS(cyclicGraph);
+        Assertions.assertThrows(IllegalArgumentException.class, () -> dfsCyclicTest.topologicalOrderDag());
+    }
 }
diff --git a/Algoritmi_2/Laboratorio/Lab5/src/DFS.java b/Algoritmi_2/Laboratorio/Lab5/src/DFS.java
index 6e1db65ea45e67da9c494e0ec1ace6cdc3b58dac..a5a2aa78474ace6e9079beb354b290c07ae90f63 100644
--- a/Algoritmi_2/Laboratorio/Lab5/src/DFS.java
+++ b/Algoritmi_2/Laboratorio/Lab5/src/DFS.java
@@ -6,21 +6,25 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
-public class DFS {
+public
+class DFS {
 
     private GraphInterface myGraph;
     private boolean[] founded;
     private GraphInterface treeDFS;
+    private int[] fathers;
 
     private ArrayList<Integer> postVisitOrder = new ArrayList<>();
 
-    public DFS(GraphInterface g) {
+    public
+    DFS(GraphInterface g) {
         this.myGraph = g;
         this.founded = new boolean[this.myGraph.getOrder()];
         this.treeDFS = this.myGraph.create();
     }
 
-    private void visitaDFS(int sorg) {
+    private
+    void visitaDFS(int sorg) {
         if (sorg >= this.myGraph.getOrder() || sorg < 0) {
             throw new IllegalArgumentException("Sorgente non presenten nel grafo");
         }
@@ -34,12 +38,14 @@ public class DFS {
         postVisitOrder.add(sorg);
     }
 
-    public GraphInterface getTree(int sorg) {
+    public
+    GraphInterface getTree(int sorg) {
         visitaDFS(sorg);
         return this.treeDFS;
     }
 
-    public GraphInterface getTreeRicoprente(int sorg) throws NotAllNodesReachedException {
+    public
+    GraphInterface getTreeRicoprente(int sorg) throws NotAllNodesReachedException {
         visitaDFS(sorg);
         if (treeDFS.getOrder() != myGraph.getOrder() - 1) {
             throw new NotAllNodesReachedException("Esistono due alberi");
@@ -47,7 +53,8 @@ public class DFS {
         return this.treeDFS;
     }
 
-    public GraphInterface getForest() {
+    public
+    GraphInterface getForest() {
         for (int node = 0; node < this.myGraph.getOrder(); node++) {
             if (!this.founded[node]) {
                 getTree(node);
@@ -56,7 +63,63 @@ public class DFS {
         return this.treeDFS;
     }
 
-    public ArrayList<Integer> topologicalOrder() {
+    private
+    boolean hasDirCycleImpl(int sorg) {
+        founded[sorg] = true;
+        for (Integer node : myGraph.getNeighbors(sorg)) {
+            if (!founded[node]) {
+                fathers[node] = sorg;
+                if (hasDirCycleImpl(node)) {
+                    return true;
+                }
+            } else if (fathers[sorg] != -1 && node != fathers[sorg]) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public
+    boolean hasDirCycle() {
+        if (myGraph instanceof UndirectedGraph) {
+            throw new IllegalArgumentException("Impossibile usare hasDirCycle su un grafo non orientato");
+        }
+        for (int i = 0; i < myGraph.getOrder(); i++) {
+            fathers = new int[myGraph.getOrder()];
+            Arrays.fill(fathers, -1);
+            founded = new boolean[myGraph.getOrder()];
+            Arrays.fill(founded, false);
+            if (hasDirCycleImpl(i)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+
+    public
+    ArrayList<Integer> topologicalOrder() {
+        postVisitOrder.clear();
+        Arrays.fill(founded, false);
+        if (myGraph instanceof UndirectedGraph) {
+            throw new IllegalArgumentException("Graph need to be Directed!");
+        }
+        for (int node = 0; node < this.myGraph.getOrder(); node++) {
+            if (!founded[node]) {
+                visitaDFS(node);
+            }
+        }
+        ArrayList<Integer> topologicOrder = postVisitOrder;
+        Collections.reverse(topologicOrder);
+        return topologicOrder;
+    }
+
+    public
+    ArrayList<Integer> topologicalOrderDag() {
+        if (hasDirCycle()) {
+            throw new IllegalArgumentException("Il grafo non è un DAG");
+        }
+
         postVisitOrder.clear();
         Arrays.fill(founded, false);
         if (myGraph instanceof UndirectedGraph) {