Given a connected undirected graph, find its critical nodes (articulation points). A critical node is a node which its removal leaves the graph disconnected.
A straight-forward solution –to remove each node and do a DFS check for connectivity– will get an AC, but this is an implementation that uses Tarjan’s DFS algorithm for finding Articulation Point:
#include <algorithm> #include <iostream> #include <fstream> #include <cstring> #include <limits> #include <sstream> #include <string> #include <stack> #include <queue> #include <map> #include <set> using namespace std; set<int> apNodes, apVis; set<pair<int, int> > apEdges; void articulationPointAndBridge(map<int, map<int, int> > &graph, int s) { // cout << "ARTICULATION POINT AND BRIDGE" << endl; map<int, int> parent, num_dfs, num_low; int children_s = 0, num_dfs_size = 0; stack<int> stk; parent[s] = s, stk.push(s); // dfs while (stk.size()) { int u = stk.top(); // grey if (apVis.find(u) == apVis.end()) { num_dfs[u] = num_low[u] = num_dfs_size++; apVis.insert(u); children_s += u != s && parent[u] == s; for (map<int, int>::reverse_iterator v = graph[u].rbegin(); v != graph[u].rend(); ++v) // grey to white if (apVis.find(v->first) == apVis.end()) parent[v->first] = u, stk.push(v->first); // grey to grey else if (parent[u] != v->first) num_low[u] = min(num_low[u], num_dfs[v->first]); } // black else { if (parent[u] != u) { // POINTS if (num_dfs[parent[u]] <= num_low[u]) apNodes.insert(parent[u]); // BRIDGES if (num_dfs[parent[u]] < num_low[u]) if (u < parent[u]) apEdges.insert(make_pair(u, parent[u])); else apEdges.insert(make_pair(parent[u], u)); num_low[parent[u]] = min(num_low[parent[u]], num_low[u]); } stk.pop(); } } apNodes.erase(s); if (children_s > 1) apNodes.insert(s); } int main() { int n; string line; while (cin >> n && n) { // input getline(cin, line); bool inputDone = false; map<int, map<int, int> > graph; while (!inputDone) { getline(cin, line); stringstream ss(line); int u, v; ss >> u; if (!u) inputDone = true; while (ss >> v) graph[u][v] = 1, graph[v][u] = 1; } // solve apVis.clear(), apNodes.clear(), apEdges.clear(); articulationPointAndBridge(graph, graph.begin()->first); cout << apNodes.size() << endl; } }