美文网首页
LeetCode #1192 Critical Connecti

LeetCode #1192 Critical Connecti

作者: air_melt | 来源:发表于2022-07-11 19:26 被阅读0次

    1192 Critical Connections in a Network 查找集群内的「关键连接」

    Description:
    There are n servers numbered from 0 to n - 1 connected by undirected server-to-server connections forming a network where connections[i] = [ai, bi] represents a connection between servers ai and bi. Any server can reach other servers directly or indirectly through the network.

    A critical connection is a connection that, if removed, will make some servers unable to reach some other server.

    Return all critical connections in the network in any order.

    Example:

    Example 1:

    [图片上传失败...(image-60ac7f-1657538772848)]

    Input: n = 4, connections = [[0,1],[1,2],[2,0],[1,3]]
    Output: [[1,3]]
    Explanation: [[3,1]] is also accepted.

    Example 2:

    Input: n = 2, connections = [[0,1]]
    Output: [[0,1]]

    Constraints:

    2 <= n <= 10^5
    n - 1 <= connections.length <= 10^5
    0 <= ai, bi <= n - 1
    ai != bi
    There are no repeated connections.

    题目描述:
    力扣数据中心有 n 台服务器,分别按从 0 到 n-1 的方式进行了编号。它们之间以「服务器到服务器」点对点的形式相互连接组成了一个内部集群,其中连接 connections 是无向的。从形式上讲,connections[i] = [a, b] 表示服务器 a 和 b 之间形成连接。任何服务器都可以直接或者间接地通过网络到达任何其他服务器。

    「关键连接」 是在该集群中的重要连接,也就是说,假如我们将它移除,便会导致某些服务器无法访问其他服务器。

    请你以任意顺序返回该集群内的所有 「关键连接」。

    示例 :

    示例 1:

    [图片上传失败...(image-10997b-1657538772851)]

    输入:n = 4, connections = [[0,1],[1,2],[2,0],[1,3]]
    输出:[[1,3]]
    解释:[[3,1]] 也是正确的。

    示例 2:

    输入:n = 2, connections = [[0,1]]
    输出:[[0,1]]

    提示:

    1 <= n <= 10^5
    n-1 <= connections.length <= 10^5
    connections[i][0] != connections[i][1]
    不存在重复的连接

    思路:

    tarjan 算法
    dfn: 深度优先搜索遍历时结点 u 被搜索的次序
    low: 能够回溯到的最早的已经在栈中的结点. 设以 u 为根的子树为 tree. low 定义为以下结点的 的最小值: tree中的结点或者从 tree 通过一条不在搜索树上的边能到达的结点
    所有在环上的点都不是所求结点
    搜索 dfn[u] < low[v] 的结点即为所求结点
    时间复杂度为 O(n + m), 空间复杂度为 O(n + m), m 为边数, 即数组 connections 的大小

    代码:
    C++:

    class Solution 
    {
    public:
        vector<vector<int>> criticalConnections(int n, vector<vector<int>>& connections) 
        {
            int dfs_id = 0, dfn[100005], low[100005];
            vector<vector<int>> graph(n), result;
            for (const auto& c : connections)
            {
                graph[c.front()].emplace_back(c.back());
                graph[c.back()].emplace_back(c.front());
            }
            memset(dfn, 0, n * sizeof(int));
            memset(low, 0, n * sizeof(int));
            auto tarjan = [&](auto&& tarjan, int u, int p) -> void 
            {
                dfn[u] = low[u] = ++dfs_id;
                for (const auto &v: graph[u]) 
                {
                    if (v == p) continue;
                    if (!dfn[v]) 
                    {
                        tarjan(tarjan, v, u);
                        low[u] = min(low[u], low[v]);
                        if (low[v] > dfn[u]) result.emplace_back(vector<int>{u, v});
                    } else low[u] = min(low[u], dfn[v]);
                }
            };
            tarjan(tarjan, 0, -1);
            return result;
        }
    };
    

    Java:

    class Solution {
        public List<List<Integer>> criticalConnections(int n, List<List<Integer>> connections) {
            List<List<Integer>> graph = new ArrayList<>(n), result = new ArrayList<>();
            for (int i = 0; i < n; i++) graph.add(new ArrayList<>());
            for (List<Integer> c : connections) {
                graph.get(c.get(0)).add(c.get(1));
                graph.get(c.get(1)).add(c.get(0));
            }
            int[] dfn = new int[100_005], low = new int[100_005];
            tarjan(graph, result, 0, -1, 0, dfn, low);
            return result;
        }
        
        private void tarjan(List<List<Integer>> graph, List<List<Integer>> result, int u, int p, int id, int[] dfn, int[] low) {
            dfn[u] = low[u] = ++id;
            for (int v : graph.get(u)) {
                if (v == p) continue;
                if (dfn[v] == 0) {
                    tarjan(graph, result, v, u, id, dfn, low);
                    low[u] = Math.min(low[u], low[v]);
                    if (low[v] > dfn[u]) result.add(new ArrayList<>(){{
                        add(u);
                        add(v);
                    }});
                } else low[u] = Math.min(low[u], dfn[v]);
            }
        }
    }
    

    Python:

    class Solution:
        def criticalConnections(self, n: int, connections: List[List[int]]) -> List[List[int]]:
            graph, result, dfn, low = defaultdict(list), [], [0] * 100005, [0] * 100005
            for u, v in connections:
                graph[u].append(v)
                graph[v].append(u)
            
            def tarjan(u: int, p: int, dfs_id: int) -> None:
                dfn[u] = low[u] = dfs_id + 1
                for v in graph[u]:
                    if v == p:
                        continue
                    if not dfn[v]:
                        tarjan(v, u, dfs_id + 1)
                        low[u] = min(low[u], low[v])
                        if low[v] > dfn[u]:
                            result.append([u, v])
                    else:
                        low[u] = min(low[u], dfn[v])
                        
            tarjan(0, -1, 0)
            return result
    

    相关文章

      网友评论

          本文标题:LeetCode #1192 Critical Connecti

          本文链接:https://www.haomeiwen.com/subject/vxgnbrtx.html