var criticalConnections = function (n, connections) {
const adjList = buildGraph(n, connections),
visited = new Array(n).fill(-1),
arrival = new Array(n).fill(-1),
oldestArrival = new Array(n).fill(-1),
parent = new Array(n).fill(-1),
departure = new Array(n).fill(-1),
result = []
let timestamp = 0
dfs(0)
return result
// -----------------------------------------------
function dfs(source) {
arrival[source] = timestamp
timestamp++
oldestArrival[source] = arrival[source]
visited[source] = 1
for (const neighbor of adjList[source]) {
if (visited[neighbor] === -1) {
parent[neighbor] = source
oldestArrival[source] = Math.min(oldestArrival[source], dfs(neighbor))
} else {
// This is a back edge, hence a cycle
if (neighbor !== parent[source]) {
oldestArrival[source] = Math.min(
oldestArrival[source],
arrival[neighbor]
)
}
}
}
if (oldestArrival[source] === arrival[source] && source !== 0)
result.push([source, parent[source]])
departure[source] = timestamp
timestamp++
return oldestArrival[source]
}
// -----------------------------------------------
function buildGraph(n, edges) {
const adjList = new Array(n).fill().map(() => [])
for (const [src, dest] of edges) {
adjList[src].push(dest)
adjList[dest].push(src)
}
return adjList
}
}
// tests
console.log(
criticalConnections(4, [
[0, 1],
[1, 2],
[2, 0],
[1, 3],
])
)