Problem Statement
Given an undirected graph with V
nodes and E
edges, find a node v
(called an Articulation Point
or a Cut Vertex
) or an edge e
(Bridge
)
such that its removal would cause the graph to be disconnected.
Example: Given a computer network, find a computer (node) whose malfunction would cause the network to be severed (diconnected).
Note: A graph without any articulation points is said be be Biconnected
General Idea | \(O(V+E)\)
The general idea is to use a variation of DFS
, allowing us to use the the
implicit DFS Tree formed to decide whether or not a node/edge is an
articulation point/bridge.
A node u
is considered an articulation point in one of two cases:
u
is the root of the DFS Tree and has more than one child (If it had only one child, its removal would simply mean the graph is not disconnected, it just has one less node in it.)u
is not the root of the DFS Tree but has a child nodev
such thatv
has a back-edge to one ofu
’s ancestors. (i.e there exists a path between the two “to be disconnected” components)
To make this algorithm work, we’ll maintain two int
arrays, dfs_num[]
and
dfs_low[]
dfs_num[u]
will store the iteration count of whenu
was first visited.dfs_low[u]
will store the lowest iteration count vertexu
can reach fromu
’s current DFS Tree (i.eu
can only reach vertices of lower iteration count only if a back-edge exists in one of its children)
The node u
with a chlid v
is considered an articulation point iff
dfs_low[v] >= dfs_num[u]
which, again, would imply that that v
has no
back-edge to any of u
’s ancestors.
When it comes to edges, an edge e
, connecting nodes u
and v
,
is considered a bridge iff dfs_low[v] > dfs_num[u]
. Notice how it’s the same
condition as before but we just removed the equality.
Code
C++11 code below.
Variation
A slight variation to this problem is how many disconnected components would
result as a direct consequence of removing a vertex u
Another variation is to find the articulation vertex whose removal would cause a greater amount of components to be disconnected.
General Idea of Variation
Instead of keeping track of whether or not a node is an articulation point using
vector<bool> articulation_vertex
, we’ll use a vector<int> articulation_vertex
to
keep track of how many components will be connected after the removal of vertex u
.
To achieve this, we’ll first assume that each node in our graph G
is not
an articulation vertex. In other words, the removal of any node u
in G
will result in there being only one connected component (G
will
remain one entity and not be disconnected).
We’ll then use the same algorithm we’ve used before, however, this around around,
whenever we find that u
is an articulation vertex relative to one of its children,
we’ll increment articulation_vertex[u]
.
So, if we have a vertex u
with say, 3 child components with no back-edges, the
removal of u
will result in G
being cut into four connected components.
Code
C++11 code of the variation is below.