// doesn't matter the value, just different
#define UNVISITED -1
// need these for APB algorithm, initialized in main()
int depth, root, children;
vi lo, num, parent;
// true for index i if i identifies an articulation point
vector<bool> art_points;
// adj list representation of graph
vector<vi> adj_list;
// Find Articulation Points and Bridges
void APB(int u) {
lo[u] = num[u] = depth++; // lo[u] <= num[u]
for (auto &v : adj_list[u]) {
if (num[v] == UNVISITED) {
// tree edge
parent[v] = u;
if (u == root)
children++;
// Recurse
APB(v);
// articulation point
if (lo[v] >= num[u])
art_points[u] = true;
// bridge
if (lo[v] > num[u])
cout << "Edge " << u << " -> " << v << " is a bridge\n";
// update lo
lo[u] = min(lo[u], lo[v]);
} else if (v != parent[u]) {
// back edge, not a direct cycle
lo[u] = min(lo[u], num[v]);
}
}
}
void SolveForArticulationPointsAndBridges() {
// setup adjlist
int V;
V = 10;
// find articulation points and bridges
depth = 0;
num.assign(V, UNVISITED);
lo.assign(V, 0);
parent.assign(V, -1);
art_points.assign(V, false);
// first find bridges
cout << "Bridges:\n";
FOR(i, V) {
if (num[i] == UNVISITED) {
root = i, children = 0;
APB(i);
art_points[root] = (children > 1);
}
}
// points
cout << "Points:\n";
FOR(i, V) {
if (art_points[i])
cout << "Vertex " << i << endl;
}
}