Step by step explanation.
All credits to \n1. WilliamFiset YT bridges & articulation points\n2. HackerEarth article\n3. CLRS.\n\nLets represent a vertex in graph\n\n\n    data class Vert
All credits to \n1. [WilliamFiset YT bridges & articulation points](https://bit.ly/32L2KHT)\n2. [HackerEarth article](https://bit.ly/3gSluKF)\n3. CLRS.\n\n**Lets represent a vertex in graph**\n\n```\n    data class Vertex(val id: Int,  \n                      var d: Int = 0,  // discovered time\n                      var low: Int = Int.MAX_VALUE, // earliest discovered time\n                      var parent: Int = -1, \n                      var visited: Boolean = false,\n                      var articulationPoint: Boolean = false) // is this vertex articulation point ?\n```\n\n**Lets represent a graph**\n```\n    class Graph(val n: Int) {\n        \n        val vertices = Array(n) { i -> Vertex(i) } // store all vertices in array, initialise id of vertex with array index\n        \n        val adjList = Array(n) { LinkedList<Vertex>() } // adj list - array of linkedlist\n        \n        fun addEdge(from: Int, to: Int) { \n            val (f, t) = vertices[from] to vertices[to] // Vertex objects f and t to be added to adjList\n            adjList[from].add(t) // add both since it is a un-directed graph\n            adjList[to].add(f)  // add both since it is a un-directed graph\n        }\n    }\n```\n\n\n**Lets build graph with list of connections**\n```\n    private fun buildGraph(n: Int, connections: List<List<Int>>): Graph {\n        val graph = Graph(n)\n        connections.forEach { path ->\n            val (from, to) = path[0] to path[1]\n            graph.addEdge(from, to)\n        }\n        return graph\n    }\n```\n\n**Handling low : crucial part of this problem**\nFor an edge u to v during dfs traversal,\nCase 1 : If v is not visited yet, then u\'s low would be the minimum of u and v.\nCase 2 : Else if v is visited already and v is not u\'s parent, that means there is a back edge from v to reach u (there is a cycle).\n\t\t\t then u\'s low would be min of u\'s low and v\'s discover time (since v might have discovered before)\n```\n\tif (v.visited.not()) {\n\t\tu.low = minOf(u.low, v.low)\n\t} else if (u.parent != v.id) {\n\t\tu.low = minOf(u.low, v.d)\n\t}\n```\n\n**Info : articulation point**\nA vertex of Graph is an articulation point whose removal disconnects the graph.\nAlso known as *cut-vertex/weak-point/vulnerability.*\n**For an edge u to v ->**, "u" is an articulation point if\nCase 1 : If u is a root/it\'s parent is null and u has more than 1 child\nCase 2 : If u has a parent and v.low >= u.d\n```\n\tif (u.parent == -1 && child > 1) {\n\t\tu.articulationPoint = true\n\t} else if (u.parent != -1 && v.low >= u.d) {\n\t\tu.articulationPoint = true\n\t}\n```\n\n**Info : Bridge**\nA vertex of Graph is a bridge whose removal disconnects the graph.\nAlso known as *critical-connection/weak-link.*\n**For an edge u to v ->**  if v vertex has discovery time strictly greater than that of u, then is a Bridge \n```\n\tif (v.low > u.d) bridges.add(listOf(u.id, v.id))\n```\n\n\n**Lets DFS combining bridge and articulation point**\n```\n    private fun dfs(u: Vertex, graph: Graph) {\n        time++\n        u.d = time\n        u.low = time\n        u.visited = true\n        var child = 0\n        for (v in graph.adjList[u.id]) {\n            if (v.visited.not()) {\n                child++\n                v.parent = u.id    \n                dfs(v, graph)\n                u.low = minOf(u.low, v.low)\n                if (u.parent == -1 && child > 1) {\n                    u.articulationPoint = true\n                } else if (u.parent != -1 && v.low >= u.d) {\n                    u.articulationPoint = true\n                }\n                if (v.low > u.d) bridges.add(listOf(u.id, v.id))\n            } else if (u.parent != v.id) {\n                u.low = minOf(u.low, v.d)\n            }\n        }\n    }\n```\n\n## Putting it all together\n<details><summary>Full code</summary>\n<p>\n\n```\n   \n    data class Vertex(val id: Int, \n                      var d: Int = 0, \n                      var low: Int = Int.MAX_VALUE, \n                      var parent: Int = -1, \n                      var visited: Boolean = false,\n                      var articulationPoint: Boolean = false)\n    \n    class Graph(val n: Int) {\n        \n        val vertices = Array(n) { i -> Vertex(i) }\n        \n        val adjList = Array(n) { LinkedList<Vertex>() }\n        \n        fun addEdge(from: Int, to: Int) {\n            val (f, t) = vertices[from] to vertices[to]\n            adjList[from].add(t)\n            adjList[to].add(f)\n        }\n    }\n    \n    var time = 0\n    val bridges = ArrayList<List<Int>>()\n    \n    fun criticalConnections(n: Int, connections: List<List<Int>>): List<List<Int>> {\n        val graph = buildGraph(n, connections)    \n        graph.vertices.forEach {\n            if (it.visited.not()) dfs(it, graph)\n        }\n        return bridges\n    }\n    \n    private fun dfs(u: Vertex, graph: Graph) {\n        time++\n        u.d = time\n        u.low = time\n        u.visited = true\n        var child = 0\n        for (v in graph.adjList[u.id]) {\n            if (v.visited.not()) {\n                child++\n                v.parent = u.id    \n                dfs(v, graph)\n                u.low = minOf(u.low, v.low)\n                if (u.parent == -1 && child > 1) {\n                    u.articulationPoint = true\n                } else if (u.parent != -1 && v.low >= u.d) {\n                    u.articulationPoint = true\n                }\n                if (v.low > u.d) bridges.add(listOf(u.id, v.id))\n            } else if (u.parent != v.id) {\n                u.low = minOf(u.low, v.d)\n            }\n        }\n    }\n    \n    private fun buildGraph(n: Int, connections: List<List<Int>>): Graph {\n        val graph = Graph(n)\n        connections.forEach { path ->\n            val (from, to) = path[0] to path[1]\n            graph.addEdge(from, to)\n        }\n        return graph\n    }\n```\n</p>\n</details>
['Kotlin']