degree(vertex v) = # edges in graph touching v

We demonstrated breadth-first-search on an example, and discussed upper bounds on its running time:

- O(n
^{2}) because the outer loop executes at most n times, and each time the inner loop executes, it executes at most n times. - O(n+m) because the time can be counted as ∑
_{vertices w}1+degree(w) = n+2m . Here n is the number of vertices and m is the number of edges.

O(n+m) is linear in the input size, because encoding the graph takes Θ(n+m) space.

Algorithms that run in time linear in the input size are often the best possible, because for many problems, any algorithm must at least examine the entire input.

Defined cut vertex (in a connected graph) as a vertex whose removal disconnects the graph.

Discussed algorithms for identifying the cut vertices in a graph:

1) For each vertex w, remove w from the graph and see if the graph becomes disconnected, using DFS or BFS.

Time for this one is O(n(n+m)).

2) To get a faster algorithm, consider the DFS tree of the graph. In particular, consider the back edges:

The graph is on the left, the cut vertices are in green.

The DFS tree is on the right, the back edges are the dotted edges.

A non-root vertex U is a cut vertex if and only if one of its children W in the DFS tree has the following property:

- there is no descendant of W with a back edge reaching above U.

To determine whether this property holds for a vertex, define:

- The
*dfs-number*of each vertex by labelling the vertices 1,2,...,n in the order in which DFS first encounters them. Above the dfs-number of each vertex is shown in green next to the vertex. - For each vertex v, low[v] = min { dfs-number[v] , min { dfs-number[w] : (u,w) is a back edge for some descendant u of v }}. That is, low[v] is the smallest dfs-number reachable by taking tree edges down from v and then at most one back edge up.

Then, a non-root vertex U is a cut vertex if and only if one of its children W in the DFS tree has

- low[W] >= dfs-number[U].

(Prove this.)

A root vertex is a cut vertex if and only if it has two or more children in the DFS tree (using just tree edges).

(Prove this too.)

To finish, the low[] numbers can be computed bottom-up using the DFS tree using the recurrence relation:

- low[v] = min { dfs-number[v], min {dfs-number[w] : (v,w) is a back edge}, min {low[w] : w is a child of v in the dfs-tree } }

This computation takes O(n+m) time.

To summarize, here is the outline of an O(n+m)-time algorithm for identifying cut vertices:

- Do a DFS on the graph.
- Compute the dfs number for each vertex.
- Compute the low number for each vertex.
- The cut vertices are the non-root vertices U having a child V such that low[V] >= dfs-number[U], plus the root vertex, if the root vertex has degree two or more in the dfs tree.