Java implementation of Tarjan Algorithm with explanation
Basically, it uses dfs to travel through the graph to find if current vertex u, can travel back to u or previous vertex\nlow[u] records the lowest vertex u can 
Basically, it uses dfs to travel through the graph to find if current vertex u, can travel back to u or previous vertex\nlow[u] records the lowest vertex u can reach\ndisc[u] records the time when u was discovered\n```\npublic List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {\n\tint[] disc = new int[n], low = new int[n];\n\t// use adjacency list instead of matrix will save some memory, adjmatrix will cause MLE\n\tList<Integer>[] graph = new ArrayList[n];\n\tList<List<Integer>> res = new ArrayList<>();\n\tArrays.fill(disc, -1); // use disc to track if visited (disc[i] == -1)\n\tfor (int i = 0; i < n; i++) {\n\t\tgraph[i] = new ArrayList<>();\n\t}\n\t// build graph\n\tfor (int i = 0; i < connections.size(); i++) {\n\t\tint from = connections.get(i).get(0), to = connections.get(i).get(1);\n\t\tgraph[from].add(to);\n\t\tgraph[to].add(from);\n\t}\n\n\tfor (int i = 0; i < n; i++) {\n\t\tif (disc[i] == -1) {\n\t\t\tdfs(i, low, disc, graph, res, i);\n\t\t}\n\t}\n\treturn res;\n}\n\nint time = 0; // time when discover each vertex\n\nprivate void dfs(int u, int[] low, int[] disc, List<Integer>[] graph, List<List<Integer>> res, int pre) {\n\tdisc[u] = low[u] = ++time; // discover u\n\tfor (int j = 0; j < graph[u].size(); j++) {\n\t\tint v = graph[u].get(j);\n\t\tif (v == pre) {\n\t\t\tcontinue; // if parent vertex, ignore\n\t\t}\n\t\tif (disc[v] == -1) { // if not discovered\n\t\t\tdfs(v, low, disc, graph, res, u);\n\t\t\tlow[u] = Math.min(low[u], low[v]);\n\t\t\tif (low[v] > disc[u]) {\n\t\t\t\t// u - v is critical, there is no path for v to reach back to u or previous vertices of u\n\t\t\t\tres.add(Arrays.asList(u, v));\n\t\t\t}\n\t\t} else { // if v discovered and is not parent of u, update low[u], cannot use low[v] because u is not subtree of v\n\t\t\tlow[u] = Math.min(low[u], disc[v]);\n\t\t}\n\t}\n}\n```
[]