diff --git a/Source/Graph.cpp b/Source/Graph.cpp
index 177c4d5..3d94544 100644
--- a/Source/Graph.cpp
+++ b/Source/Graph.cpp
@@ -54,7 +54,7 @@ void Graph::Print()
     }
 }
 
-void Graph::TransitiveClosure()
+void Graph::TransitiveReduction1()
 {
     int m1[length][length];
     int m2[length][length];
@@ -182,3 +182,334 @@ void Graph::TransitiveClosure()
         cout << endl;
     }
 }
+
+void Graph::TransitiveReduction2()
+{
+    int closure[this->length][this->length];
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = 0; j < this->length; j++)
+        {
+            closure[i][j] = 0;
+        }
+    }
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = this->adj[i].begin(); j != this->adj[i].end(); j++)
+        {
+            closure[i][*j] = 1;
+        }
+    }
+
+    cout << "\nG1:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+
+            cout << closure[i][j] << " ";
+        }
+
+        cout << endl;
+    }
+
+    for (auto k = 0; k < this->length; k++)
+    {
+        for (auto i = 0; i < this->length; i++)
+        {
+            for (auto j = 0; j < this->length; j++)
+            {
+                if (i == j)
+                {
+                    closure[i][j] = 1;
+                }
+                else
+                {
+                    closure[i][j] = closure[i][j] || (closure[i][k] && closure[k][j]);
+                }
+            }
+        }
+    }
+
+    cout << "\nTC:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+            if (i == j)
+            {
+                cout << "1 ";
+            }
+            else
+            {
+                cout << closure[i][j] << " ";
+            }
+        }
+
+        cout << endl;
+    }
+
+    int reduction[this->length][this->length];
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = 0; j < this->length; j++)
+        {
+            reduction[i][j] = 0;
+        }
+    }
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = adj[i].begin(); j != adj[i].end(); j++)
+        {
+            reduction[i][*j] = 1;
+        }
+    }
+
+    for (auto j = 0; j < this->length; j++)
+    {
+        for (auto i = 0; i < this->length; i++)
+        {
+            if (reduction[i][j] == 1)
+            {
+                for (auto k = 0; k < this->length; k++)
+                {
+                    if (reduction[j][k] == 1)
+                    {
+                        reduction[i][k] = 0;
+                    }
+                }
+            }
+        }
+    }
+
+    cout << "\nG2:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+
+            cout << reduction[i][j] << " ";
+        }
+
+        cout << endl;
+    }
+
+    for (auto k = 0; k < this->length; k++)
+    {
+        for (auto i = 0; i < this->length; i++)
+        {
+            for (auto j = 0; j < this->length; j++)
+            {
+                if (i == j)
+                {
+                    reduction[i][j] = 1;
+                }
+                else
+                {
+                    reduction[i][j] = reduction[i][j] || (reduction[i][k] && reduction[k][j]);
+                }
+            }
+        }
+    }
+
+    cout << "\nTC:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+            if (i == j)
+            {
+                cout << "1 ";
+            }
+            else
+            {
+                cout << reduction[i][j] << " ";
+            }
+        }
+
+        cout << endl;
+    }
+}
+
+void Graph::TransitiveReduction3()
+{
+    int closure[this->length][this->length];
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = 0; j < this->length; j++)
+        {
+            closure[i][j] = 0;
+        }
+    }
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = this->adj[i].begin(); j != this->adj[i].end(); j++)
+        {
+            closure[i][*j] = 1;
+        }
+    }
+
+    cout << "\nG1:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+
+            cout << closure[i][j] << " ";
+        }
+
+        cout << endl;
+    }
+
+    for (auto k = 0; k < this->length; k++)
+    {
+        for (auto i = 0; i < this->length; i++)
+        {
+            for (auto j = 0; j < this->length; j++)
+            {
+                if (i == j)
+                {
+                    closure[i][j] = 1;
+                }
+                else
+                {
+                    closure[i][j] = closure[i][j] || (closure[i][k] && closure[k][j]);
+                }
+            }
+        }
+    }
+
+    cout << "\nTC:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+            if (i == j)
+            {
+                cout << "1 ";
+            }
+            else
+            {
+                cout << closure[i][j] << " ";
+            }
+        }
+
+        cout << endl;
+    }
+
+    int reduction[this->length][this->length];
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = 0; j < this->length; j++)
+        {
+            reduction[i][j] = 0;
+        }
+    }
+
+    for (auto i = 0; i < this->length; i++)
+    {
+        for (auto j = adj[i].begin(); j != adj[i].end(); j++)
+        {
+            reduction[i][*j] = 1;
+        }
+    }
+
+    for (int v = 0; v < this->length; ++v)
+    {
+        std::vector<std::vector<int>> paths;
+
+        // Encontra todos os paths possíveis de v para outros vértices
+        for (int j = 2; j <= this->length; ++j)
+        {
+            std::vector<int> path(j);
+
+            for (int i = 0; i < j; ++i)
+            {
+                path[i] = i;
+            }
+
+            do
+            {
+                if (path[0] == v)
+                {
+                    paths.push_back(path);
+                }
+            } while (std::next_permutation(path.begin(), path.end()));
+        }
+
+        // Verifica se os paths são transitivos
+        for (const auto &path : paths)
+        {
+            for (int i = 0; i < path.size() - 2; ++i)
+            {
+                if (reduction[path[i]][path[i + 1]] == 1 && reduction[path[i + 1]][path[i + 2]] == 1)
+                {
+                    reduction[path[i]][path[i + 2]] = 0;
+                }
+            }
+        }
+    }
+
+    cout << "\nG2:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+
+            cout << reduction[i][j] << " ";
+        }
+
+        cout << endl;
+    }
+
+    for (auto k = 0; k < this->length; k++)
+    {
+        for (auto i = 0; i < this->length; i++)
+        {
+            for (auto j = 0; j < this->length; j++)
+            {
+                if (i == j)
+                {
+                    reduction[i][j] = 1;
+                }
+                else
+                {
+                    reduction[i][j] = reduction[i][j] || (reduction[i][k] && reduction[k][j]);
+                }
+            }
+        }
+    }
+
+    cout << "\nTC:" << endl;
+
+    for (int i = 0; i < this->length; i++)
+    {
+        for (int j = 0; j < this->length; j++)
+        {
+            if (i == j)
+            {
+                cout << "1 ";
+            }
+            else
+            {
+                cout << reduction[i][j] << " ";
+            }
+        }
+
+        cout << endl;
+    }
+}
diff --git a/Source/Graph.h b/Source/Graph.h
index 4ec66f6..b7a7188 100644
--- a/Source/Graph.h
+++ b/Source/Graph.h
@@ -36,6 +36,8 @@ public:
     void InsertD(int u, int v);
     void Remove(int u, int v);
     void RemoveD(int u, int v);
-    void TransitiveClosure();
+    void TransitiveReduction1();
+    void TransitiveReduction2();
+    void TransitiveReduction3();
     Graph *Clone();
 };
diff --git a/Source/Main.cpp b/Source/Main.cpp
index 7524510..72e3863 100644
--- a/Source/Main.cpp
+++ b/Source/Main.cpp
@@ -16,25 +16,14 @@ int main()
     g1->InsertD(4, 0);
     g1->InsertD(4, 2);
 
-    cout << "-- TRANSITIVE CLOSURE --" << endl;
-    g1->TransitiveClosure();
+    cout << "-- MATRIX --" << endl;
+    g1->TransitiveReduction1();
 
-    // cout << "M1:" << endl;
-    // g1->PrintIncidenceMatrix();
-    // g1->PrintAdjacencyMatrix();
-    // auto m1 = g1->GetIncidenceMatrix();
+    cout << "\n-- LOOPS --" << endl;
+    g1->TransitiveReduction2();
 
-    // Graph *g2 = g1->ToTransitiveClosure();
-    // cout << "M2:" << endl;
-    // g2->PrintIncidenceMatrix();
-    // g2->PrintAdjacencyMatrix();
-    // auto m2 = g2->GetIncidenceMatrix();
-
-    // auto m3 = Graph::MultiplyIncidenceMatrix(m1, m2);
-    // Graph *g3 = new Graph(m3);
-    // cout << "M3:" << endl;
-    // g3->PrintIncidenceMatrix();
-    // g3->PrintAdjacencyMatrix();
+    cout << "\n-- PERMUTATION --" << endl;
+    g1->TransitiveReduction3();
 
     return 0;
 }
diff --git a/Tests.txt b/Tests.txt
new file mode 100644
index 0000000..af96bc2
--- /dev/null
+++ b/Tests.txt
@@ -0,0 +1,101 @@
+-- MATRIX --
+
+M1:
+0 1 1 1 0 0 
+0 0 1 1 0 1 
+0 0 0 1 0 0 
+0 0 0 0 0 1 
+1 0 1 0 0 0 
+0 0 0 0 0 0 
+
+M2:
+1 1 1 1 0 1 
+0 1 1 1 0 1 
+0 0 1 1 0 1 
+0 0 0 1 0 1 
+1 1 1 1 1 1 
+0 0 0 0 0 1 
+
+M3:
+0 1 2 3 0 3 
+0 0 1 2 0 3 
+0 0 0 1 0 1 
+0 0 0 0 0 1 
+1 1 2 2 0 2 
+0 0 0 0 0 0 
+
+Gt:
+0 1 0 0 0 0 
+0 0 1 0 0 0 
+0 0 0 1 0 0 
+0 0 0 0 0 1 
+1 0 0 0 0 0 
+0 0 0 0 0 0 
+
+-- LOOPS --
+
+G1:
+0 1 1 1 0 0 
+0 0 1 1 0 1 
+0 0 0 1 0 0 
+0 0 0 0 0 1 
+1 0 1 0 0 0 
+0 0 0 0 0 0 
+
+TC:
+1 1 1 1 0 1 
+0 1 1 1 0 1 
+0 0 1 1 0 1 
+0 0 0 1 0 1 
+1 1 1 1 1 1 
+0 0 0 0 0 1 
+
+G2:
+0 1 0 0 0 0 
+0 0 1 0 0 1 
+0 0 0 1 0 0 
+0 0 0 0 0 1 
+1 0 0 0 0 0 
+0 0 0 0 0 0 
+
+TC:
+1 1 1 1 0 1 
+0 1 1 1 0 1 
+0 0 1 1 0 1 
+0 0 0 1 0 1 
+1 1 1 1 1 1 
+0 0 0 0 0 1 
+
+-- PERMUTATION --
+
+G1:
+0 1 1 1 0 0 
+0 0 1 1 0 1 
+0 0 0 1 0 0 
+0 0 0 0 0 1 
+1 0 1 0 0 0 
+0 0 0 0 0 0 
+
+TC:
+1 1 1 1 0 1 
+0 1 1 1 0 1 
+0 0 1 1 0 1 
+0 0 0 1 0 1 
+1 1 1 1 1 1 
+0 0 0 0 0 1 
+
+G2:
+0 1 0 1 0 0 
+0 0 1 0 0 1 
+0 0 0 1 0 0 
+0 0 0 0 0 1 
+1 0 1 0 0 0 
+0 0 0 0 0 0 
+
+TC:
+1 1 1 1 0 1 
+0 1 1 1 0 1 
+0 0 1 1 0 1 
+0 0 0 1 0 1 
+1 1 1 1 1 1 
+0 0 0 0 0 1