- Do a DFS on the graph.
- Compute the dfs number for each vertex.
- Compute the low number for each vertex using the recurrence relation...
- 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.

Recall, 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.

The argument for correctness of the algorithm for identifying cut vertices rested on the following three claims:

1. 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.

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

3. The low numbers satisfy the following 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 } }

To verify the algorithm, we need to consider carefully whether the claims are true.

In class, we did part of this. Namely, we considered carefully the first claim.

For the first claim to be true, it must be that:

- 1A. If a non-root vertex U is a cut vertex, then it will have a child W in the DFS tree such that no descendant of W has a back edge above U.

and

- 1B. If a non-root vertex U has such a child, then it is a cut vertex.

The second part (1B) is easy to argue for. If U has a child W, with no descendant of W having a back edge going to a vertex above U, then removing W disconnects the child from the parent of W.

The first part (1A) is a little less obvious. We tried to come up with a line-by-line justification:

- Suppose U is a cut vertex.
- Removing U from the graph separates the graph into at least two components.
- The root R of the DFS tree is in one of these components, say, C.
- There is at least one other component, say, C'.
- Let W be the first vertex in C' encountered by the DFS.
- Then consider where W has to be in the DFS tree...

- Since all paths from R to W go through U, W has to be a descendant of U in the DFS tree.
- Since W is the first vertex in C' encountered by the DFS, W has to be the immediate child of U in the DFS tree.
- Since all paths from R to W go through U, there cannot be a descendant of W that has a back edge going above U.

This seems to be a convincing and general argument that (1A) is true. If we accept this argument, then we believe (1A) is true. If we accept that (1B) is also true, then we believe claim (1).

To really convince ourselves that the algorithm is correct, we need to verify also that claims (2) and (3) are correct.

We will do this later (in the homework and in class).