diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index ba1ec5c7e20c12eb5b893684698eab151c4a8803..ce1c62c7c60561be6b5a9bc9f115e8966e9e5a4a 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="GradleMigrationSettings" migrationVersion="1" />
   <component name="GradleSettings">
     <option name="linkedExternalProjectsSettings">
       <GradleProjectSettings>
-        <option name="distributionType" value="DEFAULT_WRAPPED" />
         <option name="externalProjectPath" value="$PROJECT_DIR$" />
         <option name="modules">
           <set>
diff --git a/.idea/misc.xml b/.idea/misc.xml
index cf8ff73dbdd0483209669347c493bf3336cbb89c..473dca4b4babf0dbef4bec3498024da911dfda2d 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ExternalStorageConfigurationManager" enabled="true" />
   <component name="ProjectRootManager" version="2" languageLevel="JDK_18_PREVIEW" project-jdk-name="18" project-jdk-type="JavaSDK">
diff --git a/src/main/java/fr/univamu/graph/Algorithms.java b/src/main/java/fr/univamu/graph/Algorithms.java
new file mode 100644
index 0000000000000000000000000000000000000000..b981587fc3083ee81b33893ae40dbe60cb802e42
--- /dev/null
+++ b/src/main/java/fr/univamu/graph/Algorithms.java
@@ -0,0 +1,115 @@
+package fr.univamu.graph;
+
+import fr.univamu.graph.rootedtrees.RootedTree;
+
+import java.util.*;
+
+public class Algorithms {
+
+    private static final Random random = new Random();
+    //3.1
+    public static RootedTree primMST(UndirectedGraph graph){
+
+        int startVertex = random.nextInt(graph.order()); // arbitrary
+        List<Edge> edges = new ArrayList<>(graph.adjacencies.get(startVertex));
+
+        List<LinkedList<RootedTree>> childrenOfVertices = new ArrayList<>(graph.order());
+        for (int i = 0; i < graph.order(); i++) {
+            childrenOfVertices.add(new LinkedList<>());
+        }
+
+        return primMST(startVertex, childrenOfVertices, edges, graph.adjacencies);
+    }
+
+
+    private static RootedTree primMST(int startVertex, List<LinkedList<RootedTree>> childrenOfVertices, List<Edge> edges, List<List<Edge>> graphAdjacencies){
+
+        int rootVertex = startVertex;
+
+        int minVertex = -1;
+        Edge minEdge = new Edge(-1,-1,-1);
+
+        RootedTree randChild = new RootedTree(-1,new ArrayList<>());
+        childrenOfVertices.get(startVertex).add(randChild);
+
+        for (Edge edge : edges) {
+            if((edge.weight() < minEdge.weight() || minVertex == -1)){
+                if((!childrenOfVertices.get(edge.vertex1()).isEmpty()) && childrenOfVertices.get(edge.vertex2()).isEmpty()) {
+                    rootVertex = edge.vertex1();
+                    minVertex = edge.vertex2();
+                    minEdge = edge;
+                }
+                else if ((!childrenOfVertices.get(edge.vertex2()).isEmpty()) && childrenOfVertices.get(edge.vertex1()).isEmpty()) {
+                    rootVertex = edge.vertex2();
+                    minVertex = edge.vertex1();
+                    minEdge = edge;
+                }
+            }
+        }
+        if(minVertex == -1) {
+            childrenOfVertices.get(startVertex).remove(randChild);
+            return new RootedTree(startVertex, childrenOfVertices.get(startVertex));
+        }
+        edges.addAll(graphAdjacencies.get(minVertex));
+
+
+        childrenOfVertices.get(rootVertex).add(primMST(minVertex, childrenOfVertices, edges, graphAdjacencies));
+        childrenOfVertices.get(startVertex).remove(randChild);
+
+        return new RootedTree(startVertex,childrenOfVertices.get(startVertex));
+    }
+
+
+
+    public static RootedTree aldousBroderST(UndirectedGraph graph){
+
+        int startVertex = random.nextInt(graph.order()); // arbitrary
+
+        List<Boolean> visitedVertex = new ArrayList<>(graph.order());
+        for (int i = 0; i < graph.order(); i++) {
+            visitedVertex.add(false);
+        }
+
+        List<LinkedList<RootedTree>> childrenOfVertices = new ArrayList<>(graph.order());
+        for (int i = 0; i < graph.order(); i++) {
+            childrenOfVertices.add(new LinkedList<>());
+        }
+        visitedVertex.set(startVertex, true);
+        return aldousBroderST(startVertex,1, visitedVertex, childrenOfVertices, graph);
+    }
+
+
+
+    private static RootedTree aldousBroderST(int startVertex, int nbOfVisited, List<Boolean> visitedVertex, List<LinkedList<RootedTree>> childrenOfVertices, UndirectedGraph graph){
+
+
+        System.out.print(" : " + startVertex);
+        if(nbOfVisited == graph.order()) {
+            return new RootedTree(startVertex,childrenOfVertices.get(startVertex));
+        }
+        List<Integer> neighbors = new ArrayList<>();
+        for (int neighbor : graph.neighboursOf(startVertex)) {
+            neighbors.add(neighbor);
+        }
+
+        int vertex = neighbors.get(random.nextInt(neighbors.size()));
+
+        boolean wasNotVisited = false;
+        if(!visitedVertex.get(vertex)) {
+            wasNotVisited = true;
+            visitedVertex.set(vertex, true);
+            nbOfVisited++;
+        }
+
+        RootedTree child = aldousBroderST(vertex, nbOfVisited, visitedVertex, childrenOfVertices, graph);
+
+        if(wasNotVisited) {
+            childrenOfVertices.get(startVertex).add(child);
+        }
+        return new RootedTree(startVertex,childrenOfVertices.get(startVertex));
+    }
+
+
+
+
+}
diff --git a/src/main/java/fr/univamu/graph/Edge.java b/src/main/java/fr/univamu/graph/Edge.java
index dcd39687c1df8a842bf22c0bce38a72da2f7880f..16b8b294413717ae3ae301cf35b85544ee5c26e8 100644
--- a/src/main/java/fr/univamu/graph/Edge.java
+++ b/src/main/java/fr/univamu/graph/Edge.java
@@ -1,10 +1,72 @@
 package fr.univamu.graph;
 
-public record Edge(int vertex1, int vertex2) {
+import java.util.Objects;
+import java.util.Random;
+
+public class Edge {
+  private final int vertex1;
+  private final int vertex2;
+  private double weight;
+
+  public Edge(int vertex1, int vertex2) {
+    this.vertex1 = vertex1;
+    this.vertex2 = vertex2;
+    // Random Weight Generation
+    Random random = new Random();
+    this.weight = random.nextDouble();
+  }
+
+  public Edge(int vertex1, int vertex2, double weight) {
+    this.vertex1 = vertex1;
+    this.vertex2 = vertex2;
+    this.weight = weight;
+  }
 
   public int opposite(int vertex) {
     if (vertex == vertex1) return vertex2;
     if (vertex == vertex2) return vertex1;
-    throw new IllegalArgumentException(this + ".opposite(" + vertex +")");
+    throw new IllegalArgumentException(this + ".opposite(" + vertex + ")");
+  }
+
+  public int vertex1() {
+    return vertex1;
+  }
+
+  public int vertex2() {
+    return vertex2;
+  }
+
+  public double weight() {
+    return weight;
   }
+
+  public void setWeight(double weight) {
+    this.weight = weight;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (obj == this) return true;
+    if (obj == null || obj.getClass() != this.getClass()) return false;
+    var that = (Edge) obj;
+    return this.vertex1 == that.vertex1 &&
+            this.vertex2 == that.vertex2 &&
+            Objects.equals(this.weight, that.weight);
+  }
+
+  @Override
+  public int hashCode() {
+    return Objects.hash(vertex1, vertex2, weight);
+  }
+
+  @Override
+  public String toString() {
+    return "Edge["
+            + vertex1 + ", "
+            + vertex2 + ", " +
+            + weight + ']';
+  }
+
+
 }
+