#include <iostream> #include <vector> #include <set> using namespace std; void dfs(int u, int parent, vector<vector<int>>& adj, vector<int>& disc, vector<int>& low, vector<bool>& visited, set<int>& articulation_points, int& time) { visited[u] = true; disc[u] = low[u] = ++time; int children = 0; for (int v : adj[u]) { if (!visited[v]) { children++; dfs(v, u, adj, disc, low, visited, articulation_points, time); low[u] = min(low[u], low[v]); if (parent != -1 && low[v] >= disc[u]) { articulation_points.insert(u); } } else if (v != parent) { low[u] = min(low[u], disc[v]); } } if (parent == -1 && children > 1) { articulation_points.insert(u); } } int main() { int n = 5; vector<vector<int>> adj(n); adj[0] = {1, 2}; adj[1] = {0, 2}; adj[2] = {0, 1, 3}; adj[3] = {2, 4}; adj[4] = {3}; vector<int> disc(n, -1), low(n, -1); vector<bool> visited(n, false); set<int> articulation_points; int time = 0; for (int i = 0; i < n; i++) { if (!visited[i]) { dfs(i, -1, adj, disc, low, visited, articulation_points, time); } } for (int ap : articulation_points) { cout << ap << " "; } cout << endl; return 0; }
The articulation points are nodes 2 and 3 because removing either disconnects the graph. Node 2 connects the triangle (0,1,2) to node 3, and node 3 connects node 4 to the rest.
An articulation point is a vertex that, if removed along with its edges, increases the number of connected components in the graph. It is critical for connectivity.
void dfs(int u, int parent, vector<vector<int>>& adj, vector<int>& disc, vector<int>& low, vector<bool>& visited, set<int>& articulation_points, int& time) { visited[u] = true; disc[u] = low[u] = ++time; int children = 0; for (int v : adj[u]) { if (!visited[v]) { children++; dfs(v, u, adj, disc, low, visited, articulation_points, time); low[u] = min(low[u], low[v]); if (low[v] >= disc[u]) { articulation_points.insert(u); } } else if (v != parent) { low[u] = min(low[u], disc[v]); } } if (parent == -1 && children > 1) { articulation_points.insert(u); } }
The condition if (low[v] >= disc[u]) inside the loop marks articulation points, but for the root node, it should only be marked if it has more than one child. Without checking parent != -1, the root node with one child is incorrectly marked.
Vertices 1 and 5 are articulation points. Removing 1 disconnects node 3 and beyond; removing 5 disconnects node 6.
#include <iostream> #include <vector> #include <set> using namespace std; void dfs(int u, int parent, vector<vector<int>>& adj, vector<int>& disc, vector<int>& low, vector<bool>& visited, set<int>& articulation_points, int& time) { visited[u] = true; disc[u] = low[u] = ++time; int children = 0; for (int v : adj[u]) { if (!visited[v]) { children++; dfs(v, u, adj, disc, low, visited, articulation_points, time); low[u] = min(low[u], low[v]); if (parent != -1 && low[v] >= disc[u]) { articulation_points.insert(u); } } else if (v != parent) { low[u] = min(low[u], disc[v]); } } if (parent == -1 && children > 1) { articulation_points.insert(u); } } int main() { int n = 7; vector<vector<int>> adj(n); adj[0] = {1}; adj[1] = {0, 2}; adj[2] = {1}; adj[3] = {4}; adj[4] = {3, 5, 6}; adj[5] = {4}; adj[6] = {4}; vector<int> disc(n, -1), low(n, -1); vector<bool> visited(n, false); set<int> articulation_points; int time = 0; for (int i = 0; i < n; i++) { if (!visited[i]) { dfs(i, -1, adj, disc, low, visited, articulation_points, time); } } for (int ap : articulation_points) { cout << ap << " "; } cout << endl; return 0; }
In the first component (0,1,2), node 1 is an articulation point. In the second component (3,4,5,6), node 4 is an articulation point. So output is 1 and 4.
