You are on page 1of 3

Articulation Point

Articulation points in a network are those which are critical to communication: for an articulation point,
all paths between certain nodes have to pass through this point. A vertex in a connected undirected
graph is an articulation point if removing it and all edges incident to it results in a non-connected graph;
in other words, removing a vertex leads a separation of its subtree from the other part of a graph. A
connected graph is biconnected if it has no articulation points. A biconnected component of an
undirected graph G = (V, E) is a maximal subset B of the edges with the property that the graph GB = (VB,
B) is biconnected, where VB is the subset of vertices incident to edges in B. There is a very close
relationship between biconnected components and articulation points. The articulation points are
exactly the vertices at which two biconnected components are connected. Thus, the articulation point
separates the biconnected components of a graph. The idea of articulation points and biconnected
components plays an important role in any network graph in terms of its connectivity.

A complicated graph
Algorithm
In a graph G = (V,E), v is an articulation point if:

• removal of v in G results in a disconnected graph


• If v is an articulation point, then there exist distinct vertices w and x such that v is in every path
from w to x.

Finding articulation points can be nicely done by using Depth-First Search. In a DFS tree of an
undirected graph, a node u is an articulation point, for every child v of u, if there is no back edge from
v to a node higher in the DFS tree than u. That is, every node in the decedent tree of u have no way
to visit other nodes in the graph without passing through the node u, which is the articulation point.
Thus, for each node in DFS traversal, we calculate dfsnum(v) and LOW(v). The denition of LOW(v)
is the lowest dfsnum of any vertex that is either in the DFS subtree rooted at v or connected to a vertex
in that subtree by a back edge. Then, in DFS, if there is no more nodes to visit, we back up and update
the values of LOW as we return from each recursive call.

Global initialization: v.dfsnum −1, for all v.

Require: Vertex v
v.dfsnum dfsCounter + +
v.low v.dfsnum
for all edge (v, x) do
if x.dfsnum = −1 then // x is undiscovered
x.dfslevel v.dfslevel + +
v.numChildren v.numChildren + +
stack.push edge (v, x) // add this edge to the stack
ArticPointDFS(x) // recursively perform DFS at children nodes
v.low min(v.low, x.low)
if v.dfsnum = 1 then
// Special Case for root :
// Root is an artic. point i_ there are two or more children
if v.numChildren >= 2 then
articP ointList.add(v)
// Retrieve all edges in a biconnected component
while stack.top 6= (v, x) do
bccEdgeList.add(stack.pop)
else
if x.low _ v.dfsnum then
// v is artic. point separating x.
// Children of v cannot climb higher than v without passing through v.
articP ointList.add(v)
while stack.top 6= (v, x) do // Retrieve all edges in a biconnected component
bccEdgeList.add(stack.pop)
else if x.dfslevel < v.dfslevel − 1 then
// x is at a lower level than the level of v's parent, equivalent to (v, x) is a back edge
v.low min(v.low, x.dfsnum)
stack.push edge (v, x) // add the back edge to the stack
Code to Implementation:
int visit(int k) // DFS to find articulation points
{
struct node *t;
int m, min;
val[k] = ++id;
min = id;
for (t = adj[k]; t != z; t = t->next)
if (val[t->v] == unseen)
{
m = visit(t->v);
if (m < min) min = m;
if (m >= val[k]) cout << name(k);
}
else if (val[t->v] < min) min = val[t->v];
return min;
}

class EQ
{
private:
int *dad;
public:
EQ(int size);
int find(int x, int y, int doit);
};

int EQ::find(int x, int y, int doit)


{
int i = x, j = y;
while (dad[i] > 0) i = dad[i];
while (dad[j] > 0) j = dad[j];
if (doit && (i != j)) dad[j] = i;
return (i != j);
}

int EQ::find(int x, int y, int doit)


{
int t, i = x, j = y;
while (dad[i] > 0) i = dad[i];
while (dad[j] > 0) j = dad[j];
while (dad[x] > 0)
{ t = x; x = dad[x]; dad[t] = i; }
while (dad[y] > 0)
{ t = y; y = dad[y]; dad[t] = j; }
if (doit && (i != j))
if (dad[j] < dad[i])
{ dad[j] += dad[i] - 1; dad[i] = j; }
else
{ dad[i] += dad[j] - 1; dad[j] = i; }
return (i != j);
}

You might also like