Skip to content

Commit 931c9df

Browse files
committed
articulation points
1 parent a6c7a8c commit 931c9df

File tree

1 file changed

+164
-0
lines changed
  • Graph/Articulation_points

1 file changed

+164
-0
lines changed

Graph/Articulation_points/ap.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
2+
// A C++ program to find articulation points in an undirected graph
3+
4+
#include<iostream>
5+
#include <list>
6+
#define NIL -1
7+
using namespace std;
8+
9+
// A class that represents an undirected graph
10+
class Graph
11+
{
12+
int V; // No. of vertices
13+
list<int> *adj; // A dynamic array of adjacency lists
14+
void APUtil(int v, bool visited[], int disc[], int low[],
15+
int parent[], bool ap[]);
16+
public:
17+
Graph(int V); // Constructor
18+
void addEdge(int v, int w); // function to add an edge to graph
19+
void AP(); // prints articulation points
20+
};
21+
22+
Graph::Graph(int V)
23+
{
24+
this->V = V;
25+
adj = new list<int>[V];
26+
}
27+
28+
void Graph::addEdge(int v, int w)
29+
{
30+
adj[v].push_back(w);
31+
adj[w].push_back(v); // Note: the graph is undirected
32+
}
33+
34+
// A recursive function that find articulation points using DFS traversal
35+
// u --> The vertex to be visited next
36+
// visited[] --> keeps tract of visited vertices
37+
// disc[] --> Stores discovery times of visited vertices
38+
// parent[] --> Stores parent vertices in DFS tree
39+
// ap[] --> Store articulation points
40+
void Graph::APUtil(int u, bool visited[], int disc[],
41+
int low[], int parent[], bool ap[])
42+
{
43+
// A static variable is used for simplicity, we can avoid use of static
44+
// variable by passing a pointer.
45+
static int time = 0;
46+
47+
// Count of children in DFS Tree
48+
int children = 0;
49+
50+
// Mark the current node as visited
51+
visited[u] = true;
52+
53+
// Initialize discovery time and low value
54+
disc[u] = low[u] = ++time;
55+
56+
// Go through all vertices aadjacent to this
57+
list<int>::iterator i;
58+
for (i = adj[u].begin(); i != adj[u].end(); ++i)
59+
{
60+
int v = *i; // v is current adjacent of u
61+
62+
// If v is not visited yet, then make it a child of u
63+
// in DFS tree and recur for it
64+
if (!visited[v])
65+
{
66+
children++;
67+
parent[v] = u;
68+
APUtil(v, visited, disc, low, parent, ap);
69+
70+
// Check if the subtree rooted with v has a connection to
71+
// one of the ancestors of u
72+
low[u] = min(low[u], low[v]);
73+
74+
// u is an articulation point in following cases
75+
76+
// (1) u is root of DFS tree and has two or more chilren.
77+
if (parent[u] == NIL && children > 1)
78+
ap[u] = true;
79+
80+
// (2) If u is not root and low value of one of its child is more
81+
// than discovery value of u.
82+
if (parent[u] != NIL && low[v] >= disc[u])
83+
ap[u] = true;
84+
}
85+
86+
// Update low value of u for parent function calls.
87+
else if (v != parent[u])
88+
low[u] = min(low[u], disc[v]);
89+
}
90+
}
91+
92+
// The function to do DFS traversal. It uses recursive function APUtil()
93+
void Graph::AP()
94+
{
95+
// Mark all the vertices as not visited
96+
bool *visited = new bool[V];
97+
int *disc = new int[V];
98+
int *low = new int[V];
99+
int *parent = new int[V];
100+
bool *ap = new bool[V]; // To store articulation points
101+
102+
// Initialize parent and visited, and ap(articulation point) arrays
103+
for (int i = 0; i < V; i++)
104+
{
105+
parent[i] = NIL;
106+
visited[i] = false;
107+
ap[i] = false;
108+
}
109+
110+
// Call the recursive helper function to find articulation points
111+
// in DFS tree rooted with vertex 'i'
112+
for (int i = 0; i < V; i++)
113+
if (visited[i] == false)
114+
APUtil(i, visited, disc, low, parent, ap);
115+
116+
// Now ap[] contains articulation points, print them
117+
for (int i = 0; i < V; i++)
118+
if (ap[i] == true)
119+
cout << i << " ";
120+
}
121+
122+
int main()
123+
{
124+
// Create graphs given in above diagrams
125+
cout << "\nArticulation points in first graph \n";
126+
Graph g1(5);
127+
g1.addEdge(1, 0);
128+
g1.addEdge(0, 2);
129+
g1.addEdge(2, 1);
130+
g1.addEdge(0, 3);
131+
g1.addEdge(3, 4);
132+
g1.AP();
133+
134+
cout << "\nArticulation points in second graph \n";
135+
Graph g2(4);
136+
g2.addEdge(0, 1);
137+
g2.addEdge(1, 2);
138+
g2.addEdge(2, 3);
139+
g2.AP();
140+
141+
cout << "\nArticulation points in third graph \n";
142+
Graph g3(7);
143+
g3.addEdge(0, 1);
144+
g3.addEdge(1, 2);
145+
g3.addEdge(2, 0);
146+
g3.addEdge(1, 3);
147+
g3.addEdge(1, 4);
148+
g3.addEdge(1, 6);
149+
g3.addEdge(3, 5);
150+
g3.addEdge(4, 5);
151+
g3.AP();
152+
153+
return 0;
154+
}
155+
/*
156+
Explaination:
157+
158+
A O(V+E) algorithm to find all Articulation Points (APs)
159+
The idea is to use DFS (Depth First Search). In DFS, we follow vertices in tree form called DFS tree. In DFS tree, a vertex u is parent of another vertex v, if v is discovered by u (obviously v is an adjacent of u in graph). In DFS tree, a vertex u is articulation point if one of the following two conditions is true.
160+
1) u is root of DFS tree and it has at least two children.
161+
2) u is not root of DFS tree and it has a child v such that no vertex in subtree rooted with v has a back edge to one of the ancestors (in DFS tree) of u.
162+
163+
164+
*/

0 commit comments

Comments
 (0)