Adloun

Probleme – Le chemin le plus large

Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 23 — Unir & trouver, arbres couvrants

Énoncé

Le chapitre mentionne l'adaptation au chemin le plus large. On la construit ici.

Le goulot d'un chemin est le poids de son arête la plus faible. Étant donné un graphe non orienté connexe pondéré et deux sommets et , on cherche le chemin de à dont le goulot est maximal.

Corrigé

1. La preuve. Soit un arbre couvrant maximal — obtenu par Kruskal en triant par poids décroissant —, soit l'unique chemin de à dans , et soit son goulot. Montrons qu'aucun chemin ne fait mieux.

Soit une arête de réalisant le goulot, . Retirer de coupe l'arbre en deux parties et , avec et (car est sur le chemin de à ). Toute arête traversant cette coupe vérifie : sinon, serait un arbre couvrant de poids strictement supérieur, ce qui contredit la maximalité de . C'est la propriété de la coupe, retournée.

Or tout chemin de à dans le graphe doit traverser cette coupe au moins une fois, donc emprunter une arête de poids . Son goulot est donc . Le chemin est optimal.

2. L'algorithme.


(* Chemin de goulot maximal entre s et t.
   Entrees : n sommets, liste d'aretes (u, v, poids), graphe connexe.
   Sortie  : le goulot maximal. Complexite : O(m log m). *)
let goulot_maximal n aretes s t =
  (* 1. arbre couvrant MAXIMAL : Kruskal, tri DECROISSANT *)
  let triees = List.sort (fun (_,_,a) (_,_,b) -> compare b a) aretes in
  let u = creer n and arbre = Array.make n [] in
  List.iter (fun (a, b, p) ->
    if unir u a b then begin
      arbre.(a) <- (b, p) :: arbre.(a);
      arbre.(b) <- (a, p) :: arbre.(b)
    end) triees;
  (* 2. l'unique chemin de s a t dans l'arbre, par parcours en profondeur *)
  let vu = Array.make n false in
  let rec descendre x mini =
    if x = t then Some mini
    else begin
      vu.(x) <- true;
      List.fold_left (fun acc (y, p) ->
        match acc with
        | Some _ -> acc
        | None -> if vu.(y) then None else descendre y (min mini p)
      ) None arbre.(x)
    end
  in
  descendre s max_int

Complexité : pour le tri, puis un parcours en dans un arbre de arêtes. Et le même arbre répond à toutes les paires : le construire une fois coûte , puis chaque requête coûte . C'est l'argument décisif quand on a beaucoup de paires à traiter.

3. La vérification. Sur le graphe à cinq sommets

l'arbre couvrant maximal calculé est , de poids . On compare, pour les dix paires de sommets, le goulot dans cet arbre au goulot optimal calculé par énumération de tous les chemins simples :

paire0-10-20-30-41-21-31-42-32-43-4
force brute3333555766
dans l'arbre3333555766

Accord sur les dix paires.

Remarquer -. L'arête directe pèse ; le chemin optimal l'évite et passe par , de goulot . Le chemin le plus large n'est ni le plus court ni le moins cher : c'est un troisième problème, et il se trouve que l'arbre couvrant le résout aussi.

Les autres exercices de ce chapitre Le cours du chapitre

Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.