CIS 9615. Analysis of Algorithms

Graph: Optimization


1. Minimum spanning trees

For an undirected and connected graph G = (V, E), its subgraph G' = (V, T) is a spanning tree of G if G' is connected, and |T| = |V| - 1.

It's relation with the "tree" introduced before, and the related notions.

If G is also weighted, then T is a minimum spanning tree if it has the minimum value of ∑w(u, v) [for (u, v) ∈ T]. It is not necessarily unique.

Finding MST: tree building or cycle breaking.

Kruskal's algorithm each time adds an edge that have the least w, and connect two previously unconnected subgraphs. The algorithm uses disjoint-set forest to represent subtrees, and Find-Set(u) identifies the set in which u belongs, which can be done in O(lg E) time (see Section 21.3).

09-06 (26K)


Kruskal's algorithm is a greedy algorithm, and since it processes each edge in order, it takes O(E lg E) time, which can also be written as O(E lg V), given |E| ≤ |V|2.

Prim's algorithm grows a MST by adding vertices one by one into the tree, starting from a root r.

09-07 (22K)

For each vertex v, key[v] is the minimum weight of any edge connecting v to a vertex in the tree. In line 7, Extract-Min(Q) takes the vertex with the lowest key value out of Q.


Prim's algorithm also takes O(E lg V) time. See the textbook for details.


2. Single-source shortest paths

In a weighted graph, the weight of a path is the sum of the weights of the edges in the path. A shortest path is a path whose weight has the lowest value among all paths with the same source and destination vertex.

A section of a shortest path is also a shortest path. For graph G = (V, E), the shortest path contains less than |V| edges. If a graph contains a negatively-weighted cycle, then there is no shortest path on that cycle.

If all edges are equally-weighted, the breadth-first search algorithm finds shortest paths from a source vertex to all other vertices. However, it does not work if the edges have different weights.

The following algorithm initializes the distance array d and the predecessor array π.
10-01 (9K)

Many shortest-path algorithm use the "relaxation" technique, which tries to improve the shortest distance to vertex v by taking vertex u into consideration, with (u, v) as the last step. The matrix w stores the weights of the edges.
10-02 (7K)

Bellman-Ford algorithm processes the graph |V|–1 passes, and in each pass, tries the edges one-by-one to relax the distance. After that, if there is still possible relaxation, the graph contains negatively-weighted cycle.

10-03 (21K)

The running time is O(V E), though it can be stopped earlier of a whole loop does not do any update.


If the graph is a DAG, there are faster solutions. The following algorithm topologically sort the vertices first, then determine the shortest paths for each vertex in that order. It runs in Θ(V + E) time, which comes from topological sorting (and DFS).
10-05 (20K)


Dijkstra's algorithm works for directed graphs without negative weight. It repeatedly selects the vertex with the shorted path, then use it to relax the paths to other vertices.
10-07 (17K)


It is similar to MST-Prim, except here the distance is to the starting vertex, not to the MST.

Comparison among the above three algorithms.


3. All-pairs shortest paths

If we want the shortest paths between every pair of vertices, it is inefficient to repeat an algorithm for single-source, like Bellman-Ford algorithm, with each vertex as source. This solution takes Θ(n4) time.

Floyd-Warshall algorithm uses dynamic programming, and in each step adds one possible intermediate vertex into the shortest paths.
10-11 (15K)
The running time of the above algorithm is Θ(n3).

A similar algorithm calculates the transitive closure of a graph, where T(n)ij = 1 if and only if there is a path from i to j.
10-12 (22K)