12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788(**************************************************************************)(* *)(* Ocamlgraph: a generic graph library for OCaml *)(* Copyright (C) 2004-2010 *)(* Sylvain Conchon, Jean-Christophe Filliatre and Julien Signoles *)(* *)(* This software is free software; you can redistribute it and/or *)(* modify it under the terms of the GNU Library General Public *)(* License version 2.1, with the special exception on linking *)(* described in file LICENSE. *)(* *)(* This software is distributed in the hope that it will be useful, *)(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *)(* *)(**************************************************************************)moduletypeG=sigtypetmoduleV:Sig.COMPARABLEmoduleE:sigtypettypelabelvallabel:t->labelvaldst:t->V.tvalsrc:t->V.tvalcompare:t->t->intendvaliter_vertex:(V.t->unit)->t->unitvaliter_edges_e:(E.t->unit)->t->unitvaliter_succ_e:(E.t->unit)->t->V.t->unitendmoduleMake(G:G)(W:Sig.WEIGHTwithtypeedge=G.E.t)=structopenG.EmoduleH=Hashtbl.Make(G.V)moduleElt=structtypet=W.t*G.V.t(* weights are compared first, and minimal weights come first in the
queue *)letcompare(w1,v1)(w2,v2)=letcw=W.comparew2w1inifcw!=0thencwelseG.V.comparev1v2endmoduleQ=Heap.Imperative(Elt)letspanningtree_fromgr=letvisited=H.create97inletkey=H.create97inletq=Q.create17inQ.addq(W.zero,r);whilenot(Q.is_emptyq)dolet(_,u)=Q.pop_maximumqinifnot(H.memvisitedu)thenbeginH.addvisitedu();G.iter_succ_e(fune->letv=dsteinifnot(H.memvisitedv)thenbeginletwuv=W.weighteinletimprovement=tryW.comparewuv(fst(H.findkeyv))<0withNot_found->trueinifimprovementthenbeginH.replacekeyv(wuv,e);Q.addq(wuv,v)end;end)guenddone;H.fold(fun_(_,e)acc->e::acc)key[]letspanningtreeg=letr=refNoneintryG.iter_vertex(funv->r:=Somev;raiseExit)g;invalid_arg"spanningtree"withExit->match!rwith|None->assertfalse|Somer->spanningtree_fromgrend