题目描述
力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。
它们之间以「服务器到服务器」点对点的形式相互连接组成了一个内部集群,其中连接 connections 是无向的。
从形式上讲,connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服务器都可以直接或者间接地通过网络到达任何其他服务器。
「关键连接」是在该集群中的重要连接,也就是说,假如我们将它移除,便会导致某些服务器无法访问其他服务器。
请你以任意顺序返回该集群内的所有 「关键连接」。
示例 1:
输入:n = 4, connections = [[0,1],[1,2],[2,0],[1,3]]
输出:[[1,3]]
解释:[[3,1]] 也是正确的。
提示:
- 1 <= n <= 10^5
- n-1 <= connections.length <= 10^5
- connections[i][0] != connections[i][1]
- 不存在重复的连接
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/critical-connections-in-a-network
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
参考题解
环外的连接是关键连接,环内的都不是关键连接
class Solution {
public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {
Map<Integer,Set<Integer>> neighbor = new HashMap<>();
buildMap(connections,neighbor);
int[] id = new int[n];
Arrays.fill(id,-1);
List<List<Integer>> res = new ArrayList<>();
dfs(0,0,-1,id,neighbor,res);
return res;
}
public int dfs(int node,int nodeID,int par,int[] id,Map<Integer,Set<Integer>> neighbor,List<List<Integer>> res){
id[node] = nodeID;
for(Integer temNei:neighbor.get(node)){
if(temNei == par){
continue;
}else if(id[temNei] == -1){
id[node] = Math.min(id[node],dfs(temNei,nodeID+1,node,id,neighbor,res));
}else{
id[node] = Math.min(id[temNei],id[node]);
}
}
if(id[node] == nodeID && node != 0){
res.add(Arrays.asList(node,par));
}
return id[node];
}
public void buildMap(List<List<Integer>> connections,Map<Integer,Set<Integer>> neighbor){
for(List<Integer> edge:connections){
int n1 = edge.get(0);
int n2 = edge.get(1);
Set<Integer> n11 = neighbor.getOrDefault(n1,new HashSet<>());
Set<Integer> n22 = neighbor.getOrDefault(n2,new HashSet<>());
n11.add(n2);
n22.add(n1);
neighbor.put(n1,n11);
neighbor.put(n2,n22);
}
}
}