Skip to content

Instantly share code, notes, and snippets.

@magicoder10
Last active September 24, 2020 06:01
Show Gist options
  • Save magicoder10/1794b73dd1318ce53062a36b8443c4ce to your computer and use it in GitHub Desktop.
Save magicoder10/1794b73dd1318ce53062a36b8443c4ce to your computer and use it in GitHub Desktop.
Critical connection
class Solution {
public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {
// write your code here
List<List<Integer>> bridges = new LinkedList<>();
if (n < 1 || connections == null || connections.size() < 1) {
return bridges;
}
// 1. Create edge set
// 2. Build Graph
// 3. dfs
// 4. Return edges
HashSet<Long> edges = getEdges(n, connections);
HashMap<Integer, List<Integer>> graph = buildGraph(n, edges);
HashMap<Integer, Integer> ranks = new HashMap<>();
removeCycles(n, graph, 0, ranks, 0, edges);
for (long edgeKey : edges) {
Edge edge = Edge.fromKey(n, edgeKey);
List<Integer> edgeRow = new ArrayList<>();
edgeRow.add(edge.from);
edgeRow.add(edge.to);
Collections.sort(edgeRow);
bridges.add(edgeRow);
}
return bridges;
}
private int removeCycles(int n, HashMap<Integer, List<Integer>> graph, int node, HashMap<Integer, Integer> ranks, int depth, HashSet<Long> edges) {
if (ranks.containsKey(node)) {
return ranks.get(node);
}
ranks.put(node, depth);
int minRank = n;
for (int neighbor: graph.get(node)) {
if (ranks.containsKey(neighbor) && ranks.get(neighbor) == depth - 1) {
continue;
}
int rank = removeCycles(n, graph, neighbor, ranks, depth + 1, edges);
if (rank <= depth) {
edges.remove(Edge.getKey(node, neighbor, n));
edges.remove(Edge.getKey(neighbor, node, n));
minRank = Math.min(minRank, rank);
}
}
return Math.min(minRank, depth);
}
private HashMap<Integer, List<Integer>> buildGraph(int n, HashSet<Long> edges) {
HashMap<Integer, List<Integer>> graph = new HashMap<>();
for (long edgeKey: edges) {
Edge edge = Edge.fromKey(n, edgeKey);
addEdge(graph, edge.from, edge.to);
addEdge(graph, edge.to, edge.from);
}
return graph;
}
private void addEdge(HashMap<Integer, List<Integer>> graph, int from, int to) {
List<Integer> neighbors = graph.getOrDefault(from, new LinkedList<>());
neighbors.add(to);
graph.put(from, neighbors);
}
private HashSet<Long> getEdges(int n, List<List<Integer>> connections) {
HashSet<Long> edges = new HashSet<>();
for (List<Integer> connection: connections) {
int from = connection.get(0);
int to = connection.get(1);
edges.add(Edge.getKey(from, to, n));
}
return edges;
}
private static final class Edge {
int from;
int to;
Edge(int from, int to) {
this.from = from;
this.to = to;
}
static Edge fromKey(int n, long key) {
int from = (int)(key / n);
int to = (int)(key % n);
return new Edge(from, to);
}
static long getKey(int from, int to, int n) {
return (long)from * n + to;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment