* low[W] <= dfs-number[U]. |
* low[W] >= dfs-number[U]. |
We demonstrated breadth-first-search on an example, and discussed upper bounds on its running time:
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:
To determine whether this property holds for a vertex, define:
Then, a non-root vertex U is a cut vertex if and only if one of its children W in the DFS tree has
(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:
This computation takes O(n+m) time.
To summarize, here is the outline of an O(n+m)-time algorithm for identifying cut vertices: