Python solution with explaination (Faster than 99%)
\nfrom collections import defaultdict\nclass Solution:\n    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:\n        gra
```\nfrom collections import defaultdict\nclass Solution:\n    def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:\n        graph = defaultdict(list)\n        for v in connections:\n            graph[v[0]].append(v[1])\n            graph[v[1]].append(v[0])\n        \n        pre = [-1 for i in range(n)]\n        low = [-1 for i in range(n)]\n        order = 0    \n        ans = []\n        \n        def dfs(par, cur, order):\n            order += 1\n            pre[cur] = order\n            low[cur] = pre[cur]\n            for w in graph[cur]:\n                if (pre[w] == -1):\n                    dfs(cur, w, order)\n                    low[cur] = min(low[cur], low[w])\n                    if (low[w] == pre[w]):\n                        ans.append((cur, w))\n                \n                elif (w != par):\n                    low[cur] = min(low[cur], pre[w])\n        \n        dfs(0, 0, 0) # this can be any random node, since from one node can reach any other node, dfs(1, 1, 0) will also work\n\n        return ans\n```\n\nOne observation regarding bridges (critical connections in the question) in graph; none of the edges that belong to a loop can be a bridge. So in a graph such as A--B--C--A, removing any of the edge A--B, B--C and C--A will not disconnect the graph. But, for an undirected graph, the edge A--B implies B--A; and this edge could still be a bridge, where the only loop it is in is A--B--A. So, we should consider only those loops formed by a back edge. This is where the parent information you\'ve passed in the function argument helps. It will help you to not use the loops such as A--B--A.\n\nNow to identify the back edge (or the loop), A--B--C--A we use the low and pre arrays. The array pre is like the visited array in the dfs algorithm; but instead of just flagging that the vertex as visited, we identify each vertex with a different number (according to its position in the dfs tree). The low array helps to identify if there is a loop. The low array identifies the lowest numbered (from pre array) vertex that the current vertex can reach.\n\nIdea and more explaination can be found from this post: \nhttps://stackoverflow.com/questions/11218746/bridges-in-a-connected-graph/11221469#11221469\n
[]