JAVA程序设计(查找集群内的「关键连接」(LeetCode:1192))

力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。
它们之间以「服务器到服务器」点对点的形式相互连接组成了一个内部集群,其中连接 connections 是无向的。
从形式上讲,connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服务器都可以直接或者间接地通过网络到达任何其他服务器。
「关键连接」是在该集群中的重要连接,也就是说,假如我们将它移除,便会导致某些服务器无法访问其他服务器。
请你以任意顺序返回该集群内的所有 「关键连接」。

示例 1:
JAVA程序设计(查找集群内的「关键连接」(LeetCode:1192))
文章图片

输入: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]
不存在重复的连接
思路:强连通分量模板题,不懂强连通的可以戳这里,假设你已经掌握了强连通分量算法,从题目中不难看出,我们要找的就是无向连通图中的桥。

class Solution {private int t; private int[] dfn, low; private boolean[] vis; private List[] edges; private List> ans; public List> criticalConnections(int n, List> connections) {t = 0; this.dfn = new int[n]; this.low = new int[n]; this.vis = new boolean[n]; this.ans = new ArrayList<>(); this.edges = new ArrayList[n]; for (int i = 0; i < n; i++) edges[i] = new ArrayList<>(); for (List cur : connections) { int u = cur.get(0), v = cur.get(1); edges[u].add(v); edges[v].add(u); }tarjan(0, -1); return ans; }private void tarjan(int u, int pre) {vis[u] = true; dfn[u] = low[u] = ++t; for (int v : edges[u]) { if (v == pre) continue; if (!vis[v]) { tarjan(v, u); low[u] = Math.min(low[u], low[v]); if (low[v] > dfn[u]) { List tmp = new ArrayList<>(); tmp.add(u); tmp.add(v); ans.add(new ArrayList<>(tmp)); } } else low[u] = Math.min(low[u], dfn[v]); } } }

【JAVA程序设计(查找集群内的「关键连接」(LeetCode:1192))】

    推荐阅读