Solution

ID: past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2019/functional-programming-design-and-analysis-of-algorithms/8/b/solution

All edge lengths are positive, so run the Dijkstra algorithm from every source , retaining distances and a shortest-path tree of its reachable component. Each run takes with a binary heap. The following scans after each run use only additional work.
For a directed graph, inspect every closing edge and consider when is reachable. The tree route from to followed by this edge is a closed walk. Every directed cycle supplies one such upper bound by choosing any of its vertices as ; the shortest route to its predecessor is no longer than the corresponding cycle segment. Positivity lets any repeated portion be removed, so the smallest candidate is the shortest directed-cycle length.
For an undirected graph, do not combine an edge with the distance between its endpoints indiscriminately: that can count traversal of one bridge out and back as a false cycle. Instead inspect only edges absent from the current shortest-path tree, with both endpoints reachable, and consider
The two tree routes and this non-tree edge contain a genuine cycle. If they share a prefix, its cost is counted twice, so that cycle is no longer than the candidate. Every candidate is consequently at least the global shortest-cycle length.
To prove equality is attained, take a shortest cycle and a source on it. If either cycle edge incident to is absent from the tree, its candidate uses a shortest route no longer than the rest of , so it is at most the length of . Otherwise both incident edges are in the tree, and their other endpoints lie in different branches below . Along the remaining segment of , some edge crosses between different branches. Such an edge is not a tree edge. The two distances to its endpoints are bounded by the two corresponding, disjoint segments of from ; their sum plus the crossing edge is at most the length of . Thus some candidate is no greater than the optimum, completing the proof.
Return the smallest finite candidate, or report acyclicity if none exists. The total running time is , as required. The ordinary convention is a simple graph; if parallel edges are allowed, track actual edge identities when excluding tree edges, and treat a self-loop as its own cycle rather than discarding it. This is shortest cycle by repeated shortest-path trees.

New to topics? Read the docs here!