From 6e4b959e2266d44a8c72018829edbdacb45cc0f3 Mon Sep 17 00:00:00 2001
From: Orestis <orestis.malaspinas@pm.me>
Date: Mon, 27 May 2024 14:11:35 +0200
Subject: [PATCH] maj 2024

---
 slides/cours_25.md |  470 +------------
 slides/cours_26.md | 1619 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1620 insertions(+), 469 deletions(-)
 create mode 100644 slides/cours_26.md

diff --git a/slides/cours_25.md b/slides/cours_25.md
index da306e1..7c5a434 100644
--- a/slides/cours_25.md
+++ b/slides/cours_25.md
@@ -718,7 +718,7 @@ pour sommet dans graphe et sommet non-visité
 
 ## Remarque
 
-* `i` est la distance de plus cours chemin entre `v` et les sommets en cours de visite.
+* `i` est la distance de plus courts chemin entre `v` et les sommets en cours de visite.
 
 
 # Le parcours en largeur
@@ -955,471 +955,3 @@ $$
 * Réseau électrique optimal;
 * ...
 
-# Plus courts chemins à source unique
-
-* Soit un graphe, $G=(V, E)$, une fonction de pondération $w:E\rightarrow\mathbb{R}$, et un sommet $s\in V$
-  * Trouver pour tout sommet $v\in V$, le chemin de poids minimal reliant $s$ à $v$.
-* Algorithmes standards:
-  * Dijkstra (arêtes de poids positif seulement);
-  * Bellman-Ford (arêtes de poids positifs ou négatifs, mais sans cycles).
-* Comment résoudre le problèmes si tous les poids sont les mêmes?
-
-. . .
-
-* Un parcours en largeur!
-
-# Algorithme de Dijkstra
-
-## Comment chercher pour un plus court chemin?
-
-. . .
-
-```
-si distance(u,v) > distance(u,w) + distance(w,v)
-    on passe par w plutôt qu'aller directement
-```
-
-# Algorithme de Dijkstra (1 à 5)
-
-* $D$ est le tableau des distances au sommet $1$: $D[7]$ est la distance de 1 à 7.
-* Le chemin est pas forcément direct.
-* $S$ est le tableau des sommets visités.
-
-::: columns
-
-:::: column
-
-![Initialisation.](figs/dijkstra_0.png)
-
-::::
-
-:::: column
-
-. . .
-
-![1 visité, `D[2]=1`, `D[4]=3`.](figs/dijkstra_1.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra (1 à 5)
-
-::: columns
-
-:::: column
-
-![Plus court est 2.](figs/dijkstra_1.png)
-
-
-::::
-
-:::: column
-
-. . .
-
-![2 visité, `D[3]=2`, `D[7]=3`.](figs/dijkstra_2.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra (1 à 5)
-
-::: columns
-
-:::: column
-
-![Plus court est 3.](figs/dijkstra_2.png)
-
-
-::::
-
-:::: column
-
-. . .
-
-![3 visité, `D[7]=3` inchangé, `D[6]=6`.](figs/dijkstra_3.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra (1 à 5)
-
-
-::: columns
-
-:::: column
-
-![Plus court est 4 ou 7.](figs/dijkstra_3.png)
-
-
-::::
-
-:::: column
-
-. . .
-
-![4 visité, `D[7]=3` inchangé, `D[5]=9`.](figs/dijkstra_4.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra (1 à 5)
-
-::: columns
-
-:::: column
-
-![Plus court est `7`.](figs/dijkstra_4.png)
-
-
-::::
-
-:::: column
-
-. . .
-
-![7 visité, `D[5]=7`, `D[6]=6` inchangé.](figs/dijkstra_5.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra (1 à 5)
-
-::: columns
-
-:::: column
-
-![Plus court est 6.](figs/dijkstra_5.png)
-
-
-::::
-
-:::: column
-
-. . .
-
-![`6` visité, `D[5]=7` inchangé.](figs/dijkstra_6.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra (1 à 5)
-
-::: columns
-
-:::: column
-
-![Plus court est 5 et c'est la cible.](figs/dijkstra_6.png)
-
-::::
-
-:::: column
-
-. . .
-
-![The end, tous les sommets ont été visités.](figs/dijkstra_7.png)
-
-::::
-
-:::
-
-# Algorithme de Dijkstra
-
-## Idée générale
-
-* On assigne à chaque noeud une distance $0$ pour $s$, $\infty$ pour les autres.
-* Tous les noeuds sont marqués non-visités.
-* Depuis du noeud courant, on suit chaque arête du noeud vers un sommet non visité et on calcule le poids du chemin à chaque voisin et on met à jour sa distance si elle est plus petite que la distance du noeud.
-* Quand tous les voisins du noeud courant ont été visités, le noeud est mis à visité (il ne sera plus jamais visité).
-* Continuer avec le noeud à la distance la plus faible.
-* L'algorithme est terminé losrque le noeud de destination est marqué comme visité, ou qu'on a plus de noeuds qu'on peut visiter et que leur distance est infinie.
-
-# Algorithme de Dijkstra
-
-## Pseudo-code (5min, matrix)
-
-\footnotesize
-
-. . .
-
-```C
-tab dijkstra(graph, s, t)
-    pour chaque v dans graphe
-        distance[v] = infini
-        q = ajouter(q, v)
-    distance[s] = 0
-    tant que non_vide(q)
-    // sélection de u t.q. la distance dans q est min
-        u = min(q, distance)
-        si u == t // on a atteint la cible
-            retourne distance
-        q = remove(q, u)
-        // voisin de u encore dans q
-        pour chaque v dans voisinage(u, q)
-        // on met à jour la distance du voisin en passant par u 
-            n_distance = distance[u] + w(u, v)
-            si n_distance < distance[v]
-                distance[v] = n_distance
-    retourne distance
-```
-
-# Algorithme de Dijkstra
-
-* Cet algorithme, nous donne le plus court chemin mais...
-* ne nous donne pas le chemin!
-
-## Comment modifier l'algorithme pour avoir le chemin?
-
-. . .
-
-* Pour chaque nouveau noeud à visiter, il suffit d'enregistrer d'où on est venu!
-* On a besoin d'un tableau `precedent`.
-
-## Modifier le pseudo-code ci-dessus pour ce faire (3min matrix)
-
-# Algorithme de Dijkstra
-
-\footnotesize
-
-```C
-tab, tab dijkstra(graph, s, t)
-    pour chaque v dans graphe
-        distance[v] = infini
-        precedent[v] = indéfini
-        q = ajouter(q, v)
-    distance[s] = 0
-    tant que non_vide(q)
-    // sélection de u t.q. la distance dans q est min
-        u = min(q, distance) 
-        si u == t
-            retourne distance
-        q = remove(q, u)
-        // voisin de u encore dans q
-        pour chaque v dans voisinage(u, q) 
-            n_distance = distance[u] + w(u, v)
-            si n_distance < distance[v]
-                distance[v] = n_distance
-                precedent[v] = u
-    retourne distance, precedent
-```
-
-# Algorithme de Dijkstra
-
-## Comment reconstruire un chemin ?
-
-. . .
-
-```C
-pile parcours(precedent, s, t)
-    sommets = vide
-    u = t
-    // on a atteint t ou on ne connait pas de chemin
-    si u != s && precedent[u] != indéfini 
-        tant que vrai 
-            sommets = empiler(sommets, u)
-            u = precedent[u]
-            si u == s // la source est atteinte
-                retourne sommets
-    retourne sommets
-```
-
-# Algorithme de Dijkstra amélioré
-
-## On peut améliorer l'algorithme
-
-* Avec une file de priorité!
-
-## Une file de priorité est
-
-* Une file dont chaque élément possède une priorité,
-* Elle existe en deux saveurs: `min` ou `max`:
-    * File `min`: les éléments les plus petits sont retirés en premier.
-    * File `max`: les éléments les plus grands sont retirés en premier.
-* On regarde l'implémentation de la `max`.
-
-## Comment on fait ça?
-
-. . .
-
-* On insère les éléments à haute priorité tout devant dans la file!
-
-# Les files de priorité
-
-## Trois fonction principales
-
-```C
-booléen est_vide(element) // triviale
-element enfiler(element, data, priorite)
-data defiler(element)
-rien changer_priorite(element, data, priorite)
-nombre priorite(element) // utilitaire
-```
-
-## Pseudo-implémentation: structure (1min)
-
-. . .
-
-```C
-struct element
-    data
-    priorite
-    element suivant
-```
-
-# Les files de priorité
-
-## Pseudo-implémentation: enfiler (2min)
-
-. . .
-
-```C
-element enfiler(element, data, priorite)
-    n_element = creer_element(data, priorite)
-    si est_vide(element)
-        retourne n_element
-    si priorite(n_element) > priorite(element)
-        n_element.suivant = element
-        retourne n_element
-    sinon
-        tmp = element
-        prec = element
-        tant que !est_vide(tmp) && priorite < priorite(tmp)
-            prec = tmp
-            tmp = tmp.suivant
-        prev.suivant = n_element
-        n_element.suivant = tmp
-        retourne element           
-```
-
-# Les files de priorité
-
-## Pseudo-implémentation: defiler (2min)
-
-. . .
-
-```C
-data, element defiler(element)
-    si est_vide(element)
-        retourne AARGL!
-    sinon
-        tmp = element.data
-        n_element = element.suivant
-        liberer(element)
-        retourne tmp, n_element
-```
-
-# Algorithme de Dijkstra avec file de priorité min
-
-```C
-distance, precedent dijkstra(graphe, s, t):
-    distance[source] = 0
-    fp = file_p_vide()
-    pour v dans sommets(graphe)
-        si v != s
-            distance[v] = infini
-            precedent[v] = indéfini
-        fp = enfiler(fp, v, distance[v])
-    tant que !est_vide(fp)
-        u, fp = defiler(fp)
-        pour v dans voisinage de u
-            n_distance = distance[u] + w(u, v)
-            si n_distance < distance[v]
-                distance[v] = n_distance
-                precedent[v] = u
-                fp = changer_priorite(fp, v, n_distance)
-    retourne distance, precedent
-```
-
-# Algorithme de Dijkstra avec file
-
-\footnotesize
-
-```C
-distance dijkstra(graphe, s, t)
----------------------------------------------------------
-    pour v dans sommets(graphe)
-O(V)    si v != s
-            distance[v] = infini
-O(V)        fp = enfiler(fp, v, distance[v]) // notre impl est nulle
-------------------O(V * V)-------------------------------
-    tant que !est_vide(fp)
-O(1)    u, fp = defiler(fp)
----------------------------------------------------------
-O(E)    pour v dans voisinage de u
-            n_distance = distance[u] + w(u, v)
-            si n_distance < distance[v]
-                distance[v] = n_distance
-O(V)            fp = changer_priorite(fp, v, n_distance)
----------------------------------------------------------
-    retourne distance
-```
-
-* Total: $\mathcal{O}(|V|^2+|E|\cdot |V|)$:
-    * Graphe dense: $\mathcal{O}(|V|^3)$ 
-    * Graphe peu dense: $\mathcal{O}(|V|^2)$ 
-
-# Algorithme de Dijkstra avec file
-
-## On peut faire mieux
-
-* Avec une meilleure implémentation de la file de priorité:
-    * Tas binaire: $\mathcal{O}(|V|\log|V|+|E|\log|V|)$.
-    * Tas de Fibonnacci: $\mathcal{O}(|V|+|E|\log|V|)$
-* Graphe dense: $\mathcal{O}(|V|^2\log|V|)$.
-* Graphe peu dense: $\mathcal{O}(|V|\log|V|)$.
-
-# Algorithme de Dijkstra (exercice, 5min) 
-
-![L'exercice.](figs/dijkstra_exo.png){width=60%}
-
-* Donner la liste de priorité, puis...
-
-## A chaque étape donner:
-
-* Le tableau des distances à `a`;
-* Le tableau des prédécesseurs;
-* L'état de la file de priorité.
-
-# Algorithme de Dijkstra (corrigé) 
-
-![Le corrigé partie 1.](figs/dijkstra_ex_0.png)
-
-# Algorithme de Dijkstra (corrigé) 
-
-![Le corrigé partie 2.](figs/dijkstra_ex_1.png)
-
-# Algorithme de Dijkstra (corrigé) 
-
-![Le corrigé partie 3.](figs/dijkstra_ex_2.png)
-
-# Algorithme de Dijkstra (corrigé) 
-
-![Le corrigé partie 4.](figs/dijkstra_ex_3.png)
-
-# Algorithme de Dijkstra (corrigé) 
-
-![Le corrigé partie 5.](figs/dijkstra_ex_4.png)
-
-# Algorithme de Dijkstra (corrigé) 
-
-![Le corrigé partie 6.](figs/dijkstra_ex_5.png)
-
-# Limitation de l'algorithme de Dijkstra
-
-## Que se passe-t-il pour?
-
-![Exemple.](figs/exemple_neg.png){width=50%}
-
-## Quel est le problème?
-
-. . .
-
-* L'algorithme n'essaiera jamais le chemin `s->x->y->v` et prendra direct `s->v`.
-* Ce problème n'apparaît que s'il y a des poids négatifs.
-
diff --git a/slides/cours_26.md b/slides/cours_26.md
new file mode 100644
index 0000000..c468930
--- /dev/null
+++ b/slides/cours_26.md
@@ -0,0 +1,1619 @@
+---
+title: "Théorie des graphes: plus court chemin"
+date: "2024-05-28"
+---
+
+# Rappel
+
+## Comment représente-t-on un graphe?
+
+. . .
+
+* Matrice ou liste d'ajdacence
+
+# Rappel: Matrice d'adjacence
+
+::: columns
+
+:::: column
+
+## Exemple
+
+```{.mermaid format=pdf width=400 loc=figs/}
+graph LR;
+    1---2;
+    1---4;
+    2---5;
+    4---5;
+    5---3;
+```
+
+::::
+
+:::: column
+
+\footnotesize
+
+## Quelle matrice d'adjacence? 
+
+. . .
+
+```
+   || 1 | 2 | 3 | 4 | 5
+===||===|===|===|===|===
+ 1 || 0 | 1 | 0 | 1 | 0
+---||---|---|---|---|---
+ 2 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 3 || 0 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 4 || 1 | 0 | 0 | 0 | 1
+---||---|---|---|---|---
+ 5 || 0 | 1 | 1 | 1 | 0
+```
+
+::::
+
+:::
+
+# Rappel: La liste d'adjacence
+
+::: columns
+
+:::: column
+
+## Exemple
+
+![Un graphe non-orienté.](figs/ex_graph_adj.pdf){width=80%}
+
+::::
+
+:::: column
+
+
+## Quelle liste d'adjacence? 
+
+. . .
+
+![La liste d'adjacence.](figs/ex_graph_list_adj.pdf)
+
+
+::::
+
+:::
+
+# Algorithmes de plus courts chemins
+
+\Huge
+
+Algorithmes de plus courts chemins
+
+# Contexte: les réseaux (informatique, transport, etc.)
+
+* Graphe orienté;
+* Source: sommet `s`;
+* Destination: sommet `t`;
+* Les arêtes ont des poids (coût d'utilisation, distance, etc.);
+* Le coût d'un chemin est la somme des poids des arêtes d'un chemin.
+
+## Problème à résoudre
+
+* Quel est le plus court chemin entre `s` et `t`.
+
+# Plus courts chemins à source unique
+
+* Soit un graphe, $G=(V, E)$, une fonction de pondération $w:E\rightarrow\mathbb{R}$, et un sommet $s\in V$
+  * Trouver pour tout sommet $v\in V$, le chemin de poids minimal reliant $s$ à $v$.
+* Algorithmes standards:
+  * Dijkstra (arêtes de poids positif seulement);
+  * Bellman-Ford (arêtes de poids positifs ou négatifs, mais sans cycles).
+* Comment résoudre le problèmes si tous les poids sont les mêmes?
+
+. . .
+
+* Un parcours en largeur!
+
+# Algorithme de Dijkstra
+
+## Comment chercher pour un plus court chemin?
+
+. . .
+
+```
+si distance(u,v) > distance(u,w) + distance(w,v)
+    on passe par w plutôt qu'aller directement
+```
+
+# Algorithme de Dijkstra (1 à 5)
+
+* $D$ est le tableau des distances au sommet $1$: $D[7]$ est la distance de 1 à 7.
+* Le chemin est pas forcément direct.
+* $S$ est le tableau des sommets visités.
+
+::: columns
+
+:::: column
+
+![Initialisation.](figs/dijkstra_0.png)
+
+::::
+
+:::: column
+
+. . .
+
+![1 visité, `D[2]=1`, `D[4]=3`.](figs/dijkstra_1.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 2.](figs/dijkstra_1.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![2 visité, `D[3]=2`, `D[7]=3`.](figs/dijkstra_2.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 3.](figs/dijkstra_2.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![3 visité, `D[7]=3` inchangé, `D[6]=6`.](figs/dijkstra_3.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+
+::: columns
+
+:::: column
+
+![Plus court est 4 ou 7.](figs/dijkstra_3.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![4 visité, `D[7]=3` inchangé, `D[5]=9`.](figs/dijkstra_4.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est `7`.](figs/dijkstra_4.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![7 visité, `D[5]=7`, `D[6]=6` inchangé.](figs/dijkstra_5.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 6.](figs/dijkstra_5.png)
+
+
+::::
+
+:::: column
+
+. . .
+
+![`6` visité, `D[5]=7` inchangé.](figs/dijkstra_6.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra (1 à 5)
+
+::: columns
+
+:::: column
+
+![Plus court est 5 et c'est la cible.](figs/dijkstra_6.png)
+
+::::
+
+:::: column
+
+. . .
+
+![The end, tous les sommets ont été visités.](figs/dijkstra_7.png)
+
+::::
+
+:::
+
+# Algorithme de Dijkstra
+
+## Idée générale
+
+* On assigne à chaque noeud une distance $0$ pour $s$, $\infty$ pour les autres.
+* Tous les noeuds sont marqués non-visités.
+* Depuis du noeud courant, on suit chaque arête du noeud vers un sommet non visité et on calcule le poids du chemin à chaque voisin et on met à jour sa distance si elle est plus petite que la distance du noeud.
+* Quand tous les voisins du noeud courant ont été visités, le noeud est mis à visité (il ne sera plus jamais visité).
+* Continuer avec le noeud à la distance la plus faible.
+* L'algorithme est terminé losrque le noeud de destination est marqué comme visité, ou qu'on a plus de noeuds qu'on peut visiter et que leur distance est infinie.
+
+# Algorithme de Dijkstra
+
+## Pseudo-code (5min, matrix)
+
+\footnotesize
+
+. . .
+
+```C
+tab dijkstra(graph, s, t)
+    pour chaque v dans graphe
+        distance[v] = infini
+        q = ajouter(q, v)
+    distance[s] = 0
+    tant que non_vide(q)
+    // sélection de u t.q. la distance dans q est min
+        u = min(q, distance)
+        si u == t // on a atteint la cible
+            retourne distance
+        q = remove(q, u)
+        // voisin de u encore dans q
+        pour chaque v dans voisinage(u, q)
+        // on met à jour la distance du voisin en passant par u 
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+    retourne distance
+```
+
+# Algorithme de Dijkstra
+
+* Cet algorithme, nous donne le plus court chemin mais...
+* ne nous donne pas le chemin!
+
+## Comment modifier l'algorithme pour avoir le chemin?
+
+. . .
+
+* Pour chaque nouveau noeud à visiter, il suffit d'enregistrer d'où on est venu!
+* On a besoin d'un tableau `precedent`.
+
+## Modifier le pseudo-code ci-dessus pour ce faire (3min matrix)
+
+# Algorithme de Dijkstra
+
+\footnotesize
+
+```C
+tab, tab dijkstra(graph, s, t)
+    pour chaque v dans graphe
+        distance[v] = infini
+        precedent[v] = indéfini
+        q = ajouter(q, v)
+    distance[s] = 0
+    tant que non_vide(q)
+    // sélection de u t.q. la distance dans q est min
+        u = min(q, distance) 
+        si u == t
+            retourne distance
+        q = remove(q, u)
+        // voisin de u encore dans q
+        pour chaque v dans voisinage(u, q) 
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+                precedent[v] = u
+    retourne distance, precedent
+```
+
+# Algorithme de Dijkstra
+
+## Comment reconstruire un chemin ?
+
+. . .
+
+```C
+pile parcours(precedent, s, t)
+    sommets = vide
+    u = t
+    // on a atteint t ou on ne connait pas de chemin
+    si u != s && precedent[u] != indéfini 
+        tant que vrai 
+            sommets = empiler(sommets, u)
+            u = precedent[u]
+            si u == s // la source est atteinte
+                retourne sommets
+    retourne sommets
+```
+
+# Algorithme de Dijkstra amélioré
+
+## On peut améliorer l'algorithme
+
+* Avec une file de priorité!
+
+## Une file de priorité est
+
+* Une file dont chaque élément possède une priorité,
+* Elle existe en deux saveurs: `min` ou `max`:
+    * File `min`: les éléments les plus petits sont retirés en premier.
+    * File `max`: les éléments les plus grands sont retirés en premier.
+* On regarde l'implémentation de la `max`.
+
+## Comment on fait ça?
+
+. . .
+
+* On insère les éléments à haute priorité tout devant dans la file!
+
+# Les files de priorité
+
+## Trois fonction principales
+
+```C
+booléen est_vide(element) // triviale
+element enfiler(element, data, priorite)
+data defiler(element)
+rien changer_priorite(element, data, priorite)
+nombre priorite(element) // utilitaire
+```
+
+## Pseudo-implémentation: structure (1min)
+
+. . .
+
+```C
+struct element
+    data
+    priorite
+    element suivant
+```
+
+# Les files de priorité
+
+## Pseudo-implémentation: enfiler (2min)
+
+. . .
+
+```C
+element enfiler(element, data, priorite)
+    n_element = creer_element(data, priorite)
+    si est_vide(element)
+        retourne n_element
+    si priorite(n_element) > priorite(element)
+        n_element.suivant = element
+        retourne n_element
+    sinon
+        tmp = element
+        prec = element
+        tant que !est_vide(tmp) && priorite < priorite(tmp)
+            prec = tmp
+            tmp = tmp.suivant
+        prev.suivant = n_element
+        n_element.suivant = tmp
+        retourne element           
+```
+
+# Les files de priorité
+
+## Pseudo-implémentation: defiler (2min)
+
+. . .
+
+```C
+data, element defiler(element)
+    si est_vide(element)
+        retourne AARGL!
+    sinon
+        tmp = element.data
+        n_element = element.suivant
+        liberer(element)
+        retourne tmp, n_element
+```
+
+# Algorithme de Dijkstra avec file de priorité min
+
+```C
+distance, precedent dijkstra(graphe, s, t):
+    distance[source] = 0
+    fp = file_p_vide()
+    pour v dans sommets(graphe)
+        si v != s
+            distance[v] = infini
+            precedent[v] = indéfini
+        fp = enfiler(fp, v, distance[v])
+    tant que !est_vide(fp)
+        u, fp = defiler(fp)
+        pour v dans voisinage de u
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+                precedent[v] = u
+                fp = changer_priorite(fp, v, n_distance)
+    retourne distance, precedent
+```
+
+# Algorithme de Dijkstra avec file
+
+\footnotesize
+
+```C
+distance dijkstra(graphe, s, t)
+---------------------------------------------------------
+    pour v dans sommets(graphe)
+O(V)    si v != s
+            distance[v] = infini
+O(V)        fp = enfiler(fp, v, distance[v]) // notre impl est nulle
+------------------O(V * V)-------------------------------
+    tant que !est_vide(fp)
+O(1)    u, fp = defiler(fp)
+---------------------------------------------------------
+O(E)    pour v dans voisinage de u
+            n_distance = distance[u] + w(u, v)
+            si n_distance < distance[v]
+                distance[v] = n_distance
+O(V)            fp = changer_priorite(fp, v, n_distance)
+---------------------------------------------------------
+    retourne distance
+```
+
+* Total: $\mathcal{O}(|V|^2+|E|\cdot |V|)$:
+    * Graphe dense: $\mathcal{O}(|V|^3)$ 
+    * Graphe peu dense: $\mathcal{O}(|V|^2)$ 
+
+# Algorithme de Dijkstra avec file
+
+## On peut faire mieux
+
+* Avec une meilleure implémentation de la file de priorité:
+    * Tas binaire: $\mathcal{O}(|V|\log|V|+|E|\log|V|)$.
+    * Tas de Fibonnacci: $\mathcal{O}(|V|+|E|\log|V|)$
+* Graphe dense: $\mathcal{O}(|V|^2\log|V|)$.
+* Graphe peu dense: $\mathcal{O}(|V|\log|V|)$.
+
+# Algorithme de Dijkstra (exercice, 5min) 
+
+![L'exercice.](figs/dijkstra_exo.png){width=60%}
+
+* Donner la liste de priorité, puis...
+
+## A chaque étape donner:
+
+* Le tableau des distances à `a`;
+* Le tableau des prédécesseurs;
+* L'état de la file de priorité.
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 1.](figs/dijkstra_ex_0.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 2.](figs/dijkstra_ex_1.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 3.](figs/dijkstra_ex_2.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 4.](figs/dijkstra_ex_3.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 5.](figs/dijkstra_ex_4.png)
+
+# Algorithme de Dijkstra (corrigé) 
+
+![Le corrigé partie 6.](figs/dijkstra_ex_5.png)
+
+# Limitation de l'algorithme de Dijkstra
+
+## Que se passe-t-il pour?
+
+![Exemple.](figs/exemple_neg.png){width=50%}
+
+## Quel est le problème?
+
+. . .
+
+* L'algorithme n'essaiera jamais le chemin `s->x->y->v` et prendra direct `s->v`.
+* Ce problème n'apparaît que s'il y a des poids négatifs.
+
+
+# Plus cours chemin pour toute paire de sommets
+
+## Comment faire pour avoir toutes les paires?
+
+. . .
+
+* Appliquer Dijkstra sur tous les sommets d'origine.
+* Complexité:
+    * Graphe dense: $\mathcal{O}(|V|)\mathcal{O}(|V|^2\log|V|)=\mathcal{O}(|V|^3\log|V|)$.
+    * Graphe peu dense: $\mathcal{O}(|V|)\mathcal{O}(|V|\log|V|)=\mathcal{O}(|V|^2\log|V|)$.
+
+. . .
+
+## Solution alternative: Floyd--Warshall
+
+* Pour toutes paires de sommets $u,v\in V$, trouver le chemin de poids minimal reliant $u$ à $v$.
+* Complexité $\mathcal{O}(|V|^3)$, indiqué pour graphes denses.
+* Fonctionne avec la matrice d'adjacence.
+
+# Algorithme de Floyd--Warshall
+
+## Idée générale
+
+* Soit l'ensemble de sommets $V=\{1, 2, 3, 4, ..., n\}$.
+* Pour toute paire de sommets, $i,j$, on considère tous les chemins passant par les sommets intermédiaires $\in\{1, 2, ..., k\}$ avec $k\leq n$.
+* On garde pour chaque $k$ la plus petite valeur.
+
+## Principe
+
+* A chaque étape, $k$, on vérifie s'il est plus court d'aller de $i$ à $j$ en passant par le sommet $k$.
+* Si à l'étape $k-1$, le coût du parcours est $p$, on vérifie si $p$ est plus petit que $p_1+p_2$, le chemin de $i$ à $k$, et $k$ à $j$ respectivement.
+
+# Algorithme de Floyd--Warshall
+
+## The algorithme
+
+Soit $d_{ij}(k)$ le plus court chemin de $i$ à $j$ passant par les sommets $\in\{1,2,...,k\}$
+
+$$
+d_{ij}(k)=\left\{
+\begin{array}{ll}
+         w(i,j), & \mbox{si } k=0,\\
+         \min(d_{ij}(k-1),d_{ik}(k-1)+d_{kj}(k-1)), & \mbox{sinon}.
+\end{array}
+\right.
+$$
+
+# Algorithme de Floyd--Warshall (exemple)
+
+
+::: columns
+
+:::: column
+
+![Le graphe, $D=w$.](figs/floyd_exemple.png)
+
+
+::::
+
+:::: column
+
+## Que vaut $D^{(0)}$ (3min)?
+
+. . .
+
+$$
+D^{(0)}=\begin{bmatrix}
+0      & 2      & 4      & \infty & 3 \\
+2      & 0      & 8      & \infty & 1 \\
+6      & 2      & 0      & 4      & 3 \\
+1      & \infty & \infty & 0      & 5 \\
+\infty & \infty & \infty & 1      & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exemple)
+
+
+::: columns
+
+:::: column
+
+## On part de $D^{(0)}$?
+
+$$
+D^{(0)}=\begin{bmatrix}
+0      & 2      & 4      & \infty & 3 \\
+2      & 0      & 8      & \infty & 1 \\
+6      & 2      & 0      & 4      & 3 \\
+1      & \infty & \infty & 0      & 5 \\
+\infty & \infty & \infty & 1      & 0 \\
+\end{bmatrix}
+$$
+
+
+::::
+
+:::: column
+
+## Que vaut $D^{(1)}$ (3min)?
+
+. . .
+
+$$
+D^{(0)}=\begin{bmatrix}
+0      & 2          & 4               & \infty & 3 \\
+2      & 0          & \mathbf{6}      & \infty & 1 \\
+6      & 2          & 0               & 4      & 3 \\
+1      & \mathbf{3} & \mathbf{5}      & 0      & \mathbf{4} \\
+\infty & \infty     & \infty          & 1      & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exemple)
+
+
+::: columns
+
+:::: column
+
+## On part de $D^{(0)}$
+
+$$
+D^{(0)}=\begin{bmatrix}
+0      & 2      & 4      & \infty & 3 \\
+2      & 0      & 8      & \infty & 1 \\
+6      & 2      & 0      & 4      & 3 \\
+1      & \infty & \infty & 0      & 5 \\
+\infty & \infty & \infty & 1      & 0 \\
+\end{bmatrix}
+$$
+
+
+::::
+
+:::: column
+
+## Que vaut $D^{(1)}$ (3min)?
+
+. . .
+
+$$
+D^{(1)}=\begin{bmatrix}
+0      & 2          & 4               & \infty & 3 \\
+2      & 0          & \mathbf{6}      & \infty & 1 \\
+6      & 2          & 0               & 4      & 3 \\
+1      & \mathbf{3} & \mathbf{5}      & 0      & \mathbf{4} \\
+\infty & \infty     & \infty          & 1      & 0 \\
+\end{bmatrix}
+$$
+
+## Exemple
+
+$$
+D_{42}^{(1)}=D_{41}^{(0)}+D_{12}^{(0)}=1+2<\infty.
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exemple)
+
+::: columns
+
+:::: column
+
+## On part de $D^{(1)}$
+
+$$
+D^{(1)}=\begin{bmatrix}
+0      & 2          & 4      & \infty & 3 \\
+2      & 0          & 6      & \infty & 1 \\
+6      & 2          & 0      & 4      & 3 \\
+1      & 3          & 5      & 0      & 4 \\
+\infty & \infty     & \infty & 1      & 0 \\
+\end{bmatrix}
+$$
+
+
+::::
+
+:::: column
+
+## Que vaut $D^{(2)}$ (3min)?
+
+. . .
+
+$$
+D^{(2)}=\begin{bmatrix}
+0          & 2          & 4      & \infty & 3 \\
+2          & 0          & 6      & \infty & 1 \\
+\mathbf{4} & 2          & 0      & 4      & 3 \\
+1          & 3          & 5      & 0      & 4 \\
+\infty     & \infty     & \infty & 1      & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exemple)
+
+::: columns
+
+:::: column
+
+## On part de $D^{(2)}$
+
+$$
+D^{(2)}=\begin{bmatrix}
+0          & 2          & 4      & \infty & 3 \\
+2          & 0          & 6      & \infty & 1 \\
+4          & 2          & 0      & 4      & 3 \\
+1          & 3          & 5      & 0      & 4 \\
+\infty     & \infty     & \infty & 1      & 0 \\
+\end{bmatrix}
+$$
+
+
+::::
+
+:::: column
+
+## Que vaut $D^{(3)}$ (3min)?
+
+. . .
+
+$$
+D^{(3)}=\begin{bmatrix}
+0          & 2          & 4      & \mathbf{8}  & 3 \\
+2          & 0          & 6      & \mathbf{10} & 1 \\
+4          & 2          & 0      & 4           & 3 \\
+1          & 3          & 5      & 0           & 4 \\
+\infty     & \infty     & \infty & 1           & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exemple)
+
+::: columns
+
+:::: column
+
+## On part de $D^{(3)}$
+
+$$
+D^{(3)}=\begin{bmatrix}
+0          & 2          & 4      & 8  & 3 \\
+2          & 0          & 6      & 10 & 1 \\
+4          & 2          & 0      & 4  & 3 \\
+1          & 3          & 5      & 0  & 4 \\
+\infty     & \infty     & \infty & 1  & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::: column
+
+## Que vaut $D^{(4)}$ (3min)?
+
+. . .
+
+$$
+D^{(4)}=\begin{bmatrix}
+0          & 2          & 4         & 8  & 3 \\
+2          & 0          & 6         & 10 & 1 \\
+4          & 2          & 0         & 4  & 3 \\
+1          & 3          & 5         & 0  & 4 \\
+\mathbf{2} & \mathbf{4} & \mathbf{6} & 1  & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exemple)
+
+::: columns
+
+:::: column
+
+## On part de $D^{(4)}$
+
+$$
+D^{(4)}=\begin{bmatrix}
+0          & 2          & 4         & 8  & 3 \\
+2          & 0          & 6         & 10 & 1 \\
+4          & 2          & 0         & 4  & 3 \\
+1          & 3          & 5         & 0  & 4 \\
+2          & 4          & 6         & 1  & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::: column
+
+## Que vaut $D^{(5)}$ (3min)?
+
+. . .
+
+$$
+D^{(5)}=\begin{bmatrix}
+0          & 2          & 4         & \mathbf{4} & 3 \\
+2          & 0          & 6         & \mathbf{2} & 1 \\
+4          & 2          & 0         & 4          & 3 \\
+1          & 3          & 5         & 0          & 4 \\
+2          & 4          & 6         & 1          & 0 \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall
+
+## The pseudo-code (10min)
+
+* Quelle structure de données?
+* Quelle initialisation?
+* Quel est le code pour le calcul de la matrice $D$?
+
+# Algorithme de Floyd--Warshall
+
+## The pseudo-code
+
+* Quelle structure de données?
+
+```C
+int distance[n][n];
+```
+
+. . .
+
+* Quelle initialisation?
+
+```C
+matrice ini_floyd_warshall(distance, n, w)
+    pour i de 1 à n
+        pour j de 1 à n
+            distance[i][j] = w(i,j)
+    retourne distance
+```
+
+# Algorithme de Floyd--Warshall
+
+## The pseudo-code
+
+* Quel est le code pour le calcul de la matrice $D$?
+
+```C
+matrice floyd_warshall(distance, n, w)
+    pour k de 1 à n
+        pour i de 1 à n
+            pour j de 1 à n
+                distance[i][j] = min(distance[i][j], 
+                    distance[i][k] + distance[k][j])
+    retourne distance
+```
+
+# Algorithme de Floyd--Warshall
+
+## La matrice de précédence
+
+* On a pas encore vu comment reconstruire le plus court chemin!
+* On définit, $P_{ij}^{(k)}$, qui est le prédécesseur du sommet $j$ depuis $i$ avec les sommets intermédiaires $\in\{1, 2, ..., k\}$.
+$$
+P^{(0)}_{ij}=\left\{
+\begin{array}{ll}
+         \mbox{vide}, & \mbox{si } i=j\mbox{, ou }w(i,j)=\infty\\
+         i, & \mbox{sinon}.
+\end{array}
+\right.
+$$
+
+* Mise à jour
+$$
+P^{(k)}_{ij}=\left\{
+\begin{array}{ll}
+         P^{(k-1)}_{\mathbf{i}j}, & \mbox{si } d_{ij}^{(k)}\leq d_{ik}^{(k-1)}+d_{kj}^{(k-1)}\\
+         P^{(k-1)}_{\mathbf{k}j}, & \mbox{sinon}.
+\end{array}
+\right.
+$$
+
+. . .
+
+* Moralité: si le chemin est plus court en passant par $k$, alors il faut utiliser son prédécesseur!
+
+# Algorithme de Floyd--Warshall
+
+## La matrice de précédence (pseudo-code, 3min)
+
+. . .
+
+```C
+matrice, matrice floyd_warshall(distance, n, w)
+    pour k de 1 à n
+        pour i de 1 à n
+            pour j de 1 à n
+                n_distance = distance[i][k] + distance[k][j]
+                if n_distance < distance[i][j]
+                    distance[i][j] = n_distance
+                    précédence[i][j] = précédence[k][j]
+    retourne distance, précédence
+```
+
+# Algorithme de Floyd--Warshall (exercice)
+
+
+::: columns
+
+:::: column
+
+![Le graphe, $D=w$.](figs/floyd_exemple.png)
+
+
+::::
+
+:::: column
+
+## Que vaut $P^{(0)}$ (3min)?
+
+. . .
+
+$$
+P^{(0)}=\begin{bmatrix}
+-          & 1          & 1         & -          & 1 \\
+2          & -          & 2         & -          & 2 \\
+3          & 3          & -         & 3          & 3 \\
+4          & -          & -         & -          & 4 \\
+-          & -          & -         & 5          & - \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Algorithme de Floyd--Warshall (exercice)
+
+
+::: columns
+
+:::: column
+
+![Le graphe, $D=w$.](figs/floyd_exemple.png)
+
+
+::::
+
+:::: column
+
+## Que vaut $P^{(5)}$ (10min)?
+
+. . .
+
+$$
+P^{(5)}=\begin{bmatrix}
+-          & 1          & 1         & 5          & 1 \\
+2          & -          & 1         & 5          & 2 \\
+2          & 3          & -         & 3          & 3 \\
+4          & 1          & 1         & -          & 1 \\
+4          & 1          & 1         & 5          & - \\
+\end{bmatrix}
+$$
+
+::::
+
+:::
+
+# Exercice: retrouver le chemin entre 1 et 4 (5min)
+
+$$
+P=\begin{bmatrix}
+-          & 1          & 1         & 5          & 1 \\
+2          & -          & 1         & 5          & 2 \\
+2          & 3          & -         & 3          & 3 \\
+4          & 1          & 1         & -          & 4 \\
+4          & 1          & 1         & 5          & - \\
+\end{bmatrix}
+$$
+
+. . .
+
+## Solution
+
+* Le sommet $5=P_{14}$, on a donc, $5\rightarrow 4$, on veut connaître le prédécesseur de 5.
+* Le sommet $1=P_{15}$, on a donc, $1\rightarrow 5\rightarrow 4$. The end.
+
+# Exercice complet
+
+## Appliquer l'algorithme de Floyd--Warshall au graphe suivant
+
+![The exorcist.](figs/floyd_exercice.png){width=50%}
+
+* Bien indiquer l'état de $D$ et $P$ à chaque étape!
+* Ne pas oublier de faire la matrice d'adjacence évidemment...
+
+# La suite
+
+* Sans transition.... la suite!
+
+# Trouver un réseau électrique pour
+
+![Ces maisons n'ont pas d'électricité.](figs/arbre_couvrant_vide.png)
+
+# Solution: pas optimale
+
+![Le réseau simple, mais nul.](figs/arbre_couvrant_mal.png)
+
+* La longueur totale des câbles est super longue!
+
+# Solution: optimale
+
+![Le meilleur réseau.](figs/arbre_couvrant_bien.png)
+
+# Formalisation: Les arbres couvrants
+
+## Application: minimisation des coûts
+
+* Équipement d'un lotissement avec des lignes électriques/téléphoniques, des canalisations, ...
+
+. . .
+
+* Pour réduire les coûts, on cherche à minimiser la longueur totale des câbles/tuyaux.
+
+. . .
+
+* Les lignes/tuyaux forment un *arbre couvrant*.
+
+. . .
+
+* La meilleure option est un *arbre couvrant minimal*.
+
+
+# Formalisation: Les arbres couvrants
+
+* Qu'est-ce qu'un arbre couvrant? Des idées? De quel objet on part? Où va-t-on?
+
+. . .
+
+* Un arbre couvrant d'un graphe non-orienté et connexe est:
+    * un arbre inclus dans le graphe qui connecte tous les sommets du graphe.
+
+. . .
+
+![Exemple d'arbres couvrants d'un graphe connexe.](figs/arbre_couvrant_exemples.png)
+
+# Arbres couvrants
+
+* Quels algorithmes que nous avons déjà vus permettent de construire des arbres couvrants?
+
+. . .
+
+* Les parcours en largeur et en profondeur!
+
+. . .
+
+![Graphe, et parcours comme arbres couvrants.](figs/arbres_couvrants_parcours.png)
+
+# Arbres couvrants minimaux
+
+* Un *arbre couvrant minimal* est un sous-graphe d'un graphe non-orienté pondéré $G(V,E)$, tel quel:
+    * C'est un arbre (graphe acyclique);
+    * Il couvre tous les sommets de $G$ et contient $|V|-1$ arêtes;
+    * Le coût total associé aux arêtes de l'arbre est minimum parmi tous les arbres couvrants possibles.
+
+. . .
+
+* Est-il unique?
+
+. . .
+
+* Pas forcément.
+
+# Arbres couvrants minimaux
+
+* Comment générer un arbre couvrant minimal?
+
+![Un graphe, connexe, non-orienté, pondéré, et son arbre couvrant minimal.](figs/arbre_couvrant_minimal_exemple.png)
+
+# Algorithme de Prim
+
+::: columns
+
+:::: column
+
+## Un exemple
+
+![Le graphe de départ.](figs/prim_0.png)
+
+::::
+
+:::: column
+
+## On part de `e` (au hasard)
+
+![Le sommet `e` est couvert.](figs/prim_1.png)
+
+::::
+
+:::
+
+# Algorithme de Prim
+
+::: columns
+
+:::: column
+
+## On choisit comment? 
+
+![Quelle arête choisir?](figs/prim_1.png)
+
+. . .
+
+* L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
+
+::::
+
+:::: column
+
+. . .
+
+## L'arête `e->d`
+
+![Le sommet `d` est couvert.](figs/prim_2.png)
+
+::::
+
+:::
+
+# Algorithme de Prim
+
+::: columns
+
+:::: column
+
+## On choisit comment? 
+
+![Quelle arête choisir?](figs/prim_2.png)
+
+. . .
+
+* L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
+
+::::
+
+:::: column
+
+. . .
+
+## L'arête `d->a`
+
+![Le sommet `a` est couvert.](figs/prim_3.png)
+
+::::
+
+:::
+
+# Algorithme de Prim
+
+::: columns
+
+:::: column
+
+## On choisit comment? 
+
+![Quelle arête choisir?](figs/prim_3.png)
+
+. . .
+
+* L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
+
+::::
+
+:::: column
+
+. . .
+
+## L'arête `d->c`
+
+![Le sommet `c` est couvert.](figs/prim_4.png)
+
+::::
+
+:::
+
+# Algorithme de Prim
+
+::: columns
+
+:::: column
+
+## On choisit comment? 
+
+![Quelle arête choisir?](figs/prim_4.png)
+
+. . .
+
+* L'arête la plus courte sortant d'un sommet déjà visité, et entrant dans un sommet non-visité.
+
+::::
+
+:::: column
+
+. . .
+
+## L'arête `e->b`
+
+![Le sommet `b` est couvert.](figs/prim_5.png)
+
+* Game over!
+
+::::
+
+:::
+
+# Algorithme de Prim
+
+## Structures de données
+
+* Dans quoi allons nous stocker les sommets?
+
+. . .
+
+* File de priorité min.
+* Autre chose?
+
+. . .
+
+* Tableau des distances (comme pour Dijkstra).
+* Autre chose?
+
+. . .
+
+* Tableau des parents (presque comme pour Dijkstra).
+* Autre chose?
+
+. . .
+
+* Non.
+
+# Algorithme de Prim
+
+## Initialisation: Pseudo-code (2min)
+
+. . .
+
+```C
+file_priorité, distance, parent initialisation(graphe)
+    r = aléatoire(graphe)
+    distance[r] = 0
+    parent[r] = indéfini
+    fp = file_p_vide()
+    pour v dans sommets(graphe)
+        si v != r
+            distance[v] = infini
+            parent[v]   = indéfini
+        fp = enfiler(fp, v, distance[v])
+    retourne fp, distance, parent
+```
+
+# Algorithme de Prim
+
+## Algorithme: Pseudo-code (5min)
+
+. . .
+
+```C
+sommets, parent prim(file_priorité, distance, parent)
+    sommets = vide
+    tant que !est_vide(file_priorité)
+        u, fp = défiler(file_priorité)
+        sommets = insérer(sommets, u)
+        pour v dans voisinage de u et pas dans sommets 
+        // ou dans file_priorité
+            si w(u, v) < distance[v]
+                parent[w] = u
+                distance[w] = w(u, v)
+                fp = changer_priorité(fp, w, w(u, v))
+    retourne sommets, parent
+```
+
+# Exemple d'algorithme de Prim
+
+::: columns
+
+:::: {.column width="40%"}
+
+## Un exemple
+
+![Étape 1.](figs/prim_1.png)
+
+::::
+
+:::: column
+
+```
+FP |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+D  |  0  | inf | inf | inf | inf |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  -  |  -  |  -  |  -  |
+```
+
+## Devient?
+
+. . .
+
+```
+FP |  d  |  b  |  c  |  a  |
+----------------------------
+D  |  4  |  5  |  5  | inf |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  e  |  -  |
+```
+
+::::
+
+:::
+
+# Exemple d'algorithme de Prim
+
+::: columns
+
+:::: {.column width="40%"}
+
+## Un exemple
+
+![Étape 2.](figs/prim_2.png)
+
+::::
+
+:::: column
+
+```
+FP |  d  |  b  |  c  |  a  |
+----------------------------
+D  |  4  |  5  |  5  | inf |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  e  |  -  |
+```
+
+## Devient?
+
+. . .
+
+```
+FP |  a  |  c  |  b  |
+----------------------
+D  |  2  |  4  |  5  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+::::
+
+:::
+
+# Exemple d'algorithme de Prim
+
+::: columns
+
+:::: {.column width="40%"}
+
+## Un exemple
+
+![Étape 3.](figs/prim_3.png)
+
+::::
+
+:::: column
+
+```
+FP |  a  |  c  |  b  |
+----------------------
+D  |  2  |  4  |  5  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+## Devient?
+
+. . .
+
+```
+FP |  c  |  b  |
+----------------
+D  |  4  |  5  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+::::
+
+:::
+
+# Exemple d'algorithme de Prim
+
+::: columns
+
+:::: {.column width="40%"}
+
+## Un exemple
+
+![Étape 4.](figs/prim_4.png)
+
+::::
+
+:::: column
+
+```
+FP |  c  |  b  |
+----------------
+D  |  4  |  5  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+## Devient?
+
+. . .
+
+```
+FP |  b  |
+----------
+D  |  5  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+::::
+
+:::
+
+# Exemple d'algorithme de Prim
+
+::: columns
+
+:::: {.column width="40%"}
+
+## Un exemple
+
+![Étape 5.](figs/prim_4.png)
+
+::::
+
+:::: column
+
+```
+FP |  b  |
+----------
+D  |  5  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+## Devient?
+
+. . .
+
+```
+FP |
+----
+D  |
+
+   |  e  |  d  |  b  |  c  |  a  |
+----------------------------------
+P  |  -  |  e  |  e  |  d  |  d  |
+```
+
+::::
+
+:::
+
+# Exercice: algorithme de Prim
+
+## Appliquer l'algorithme de Prim à (15min):
+
+![En démarrant du sommet $V_1$.](figs/prim_exercice.png)
+
+# Exercice: algorithme de Prim
+
+## Solution
+
+![](figs/prim_solution.png)
+
+# Complexité de l'algorithme de Prim
+
+\footnotesize
+
+```C
+file_priorité, distance, parent initialisation(graphe)
+    // choix r et initialisation
+    pour v dans sommets(graphe)
+O(|V|)  // initialisation distance et parent
+        fp = enfiler(fp, v, distance[v])
+    retourne fp, distance, parent
+sommets, parent prim(file_priorité, distance, parent)
+    sommets = vide
+    tant que !est_vide(file_priorité)
+O(|V|)  u, fp = défiler(file_priorité)
+        sommets = insérer(sommets, u)
+        pour v dans voisinage de u et pas dans sommets
+    O(|E|)  si w(u, v) < distance[v]
+                // màj dista + parent
+        O(|V|)  fp = changer_priorité(fp, w, w(u, v))
+    retourne sommets, parent
+```
+
+* $O(|V|)+O(|E|)+O(|V|^2)=O(|E|+|V|^2)$
+* Remarque: $O(|E|)$ n'est pas mutliplié par $O(|V|)$, car les arêtes parcourues qu'une fois en **tout**.
-- 
GitLab