function findArticulationPoints(graph) {
const n = graph.length;
const visited = new Array(n).fill(false);
const disc = new Array(n).fill(-1);
const low = new Array(n).fill(-1);
const parent = new Array(n).fill(-1);
const ap = new Array(n).fill(false);
let time = 0;
function dfs(u) {
visited[u] = true;
disc[u] = low[u] = time++;
let children = 0;
for (const v of graph[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
dfs(v);
low[u] = Math.min(low[u], low[v]);
if (parent[u] === -1 && children > 1) ap[u] = true;
if (parent[u] !== -1 && low[v] >= disc[u]) ap[u] = true;
} else if (v !== parent[u]) {
low[u] = Math.min(low[u], disc[v]);
}
}
}
for (let i = 0; i < n; i++) {
if (!visited[i]) dfs(i);
}
const result = [];
for (let i = 0; i < n; i++) {
if (ap[i]) result.push(i);
}
return result;
}
const graph = [
[1, 2], // 0
[0, 2], // 1
[0, 1, 3, 5], // 2
[2, 4], // 3
[3], // 4
[2, 6, 7], // 5
[5, 7], // 6
[5, 6] // 7
];
console.log(findArticulationPoints(graph));The code uses DFS to find articulation points. Node 2 connects two parts of the graph, and node 5 connects another part. Removing either increases disconnected parts. Other nodes do not satisfy the articulation point conditions.
An articulation point is a vertex that, if removed, breaks the graph into more pieces, increasing the number of connected components.
function findAP(graph) {
const n = graph.length;
const visited = new Array(n).fill(false);
const disc = new Array(n).fill(-1);
const low = new Array(n).fill(-1);
const parent = new Array(n).fill(-1);
const ap = new Array(n).fill(false);
let time = 0;
function dfs(u) {
visited[u] = true;
disc[u] = low[u] = time++;
let children = 0;
for (const v of graph[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
dfs(v);
low[u] = Math.min(low[u], low[v]);
if (parent[u] === -1 && children > 1) ap[u] = true;
if (parent[u] !== -1 && low[v] >= disc[u]) ap[u] = true;
} else if (v !== parent[u]) {
low[u] = Math.min(low[u], disc[v]);
}
}
}
for (let i = 0; i < n; i++) {
if (!visited[i]) dfs(i);
}
return ap;
}The condition low[v] > disc[u] should be low[v] >= disc[u] to correctly identify articulation points when low[v] equals disc[u]. Using '>' misses some points.
const graph = [ [1, 2], // 0 [0, 2, 3], // 1 [0, 1, 4], // 2 [1, 5], // 3 [2], // 4 [3, 6, 7], // 5 [5, 7], // 6 [5, 6, 8], // 7 [7] // 8 ];
Articulation points are nodes 1, 3, and 5. Removing any of these increases disconnected parts. Other nodes do not disconnect the graph.
function articulationPoints(graph) {
const n = graph.length;
const visited = new Array(n).fill(false);
const disc = new Array(n).fill(-1);
const low = new Array(n).fill(-1);
const parent = new Array(n).fill(-1);
const ap = new Array(n).fill(false);
let time = 0;
function dfs(u) {
visited[u] = true;
disc[u] = low[u] = time++;
let children = 0;
for (const v of graph[u]) {
if (!visited[v]) {
children++;
parent[v] = u;
dfs(v);
low[u] = Math.min(low[u], low[v]);
if (parent[u] === -1 && children > 1) ap[u] = true;
if (parent[u] !== -1 && low[v] >= disc[u]) ap[u] = true;
} else if (v !== parent[u]) {
low[u] = Math.min(low[u], disc[v]);
}
}
}
for (let i = 0; i < n; i++) {
if (!visited[i]) dfs(i);
}
const result = [];
for (let i = 0; i < n; i++) {
if (ap[i]) result.push(i);
}
return result;
}
const graph = [
[1], // 0
[0, 2], // 1
[1], // 2
[4], // 3
[3, 5], // 4
[4] // 5
];
console.log(articulationPoints(graph));The graph has two disconnected parts: nodes 0-1-2 and nodes 3-4-5. Node 1 connects 0 and 2, so it's an articulation point. Node 4 connects 3 and 5, so it's also an articulation point.
