zoukankan      html  css  js  c++  java
  • Number of Operations to Make Network Connected 之 并查集

    本题的关键是要知道图论中的一个原理:无向图中, n个结点 至少需要 n-1条边,才能使各个结点相连。

    有两种解法:

    1.用递归遍历的方式,计算有多少个独立的连通的部分,我称为“簇”。需要移动的边就是 簇的个数减1。

    2.使用并查集,计算有几个联通部分,有几条多余的边。如果多余的边小于联通部分,返回-1。否则返回簇的个数减1。

    class Solution {
        Map<Integer, List<Integer>> graph = new HashMap<>();
        boolean[] visited;
        public int makeConnected(int n, int[][] connections) {
            if(connections.length < n-1) return -1;
            for(int[] edge: connections){
                graph.putIfAbsent(edge[0], new ArrayList<>());
                graph.putIfAbsent(edge[1], new ArrayList<>());
                graph.get(edge[0]).add(edge[1]);
                graph.get(edge[1]).add(edge[0]);
            }
            // true代表已经访问过,false代表未访问
            visited = new boolean[n];
            int count = 0;
            for(int i = 0; i < n; i++){
                if(!visited[i]&& dfs(i))
                    count++;
            }
            return count-1;
        }
        public boolean dfs(int cur){
            if(visited[cur]) return true;
            if(!graph.containsKey(cur)) return true;
            visited[cur] = true;
            for(int next: graph.get(cur)){
                if(!visited[next])
                    dfs(next);
            }
            return true;
        }
    }
    class Solution {
        public int makeConnected(int n, int[][] connections) {
            int[] parent = new int[n];
            for(int i = 0; i < n; i++){
                parent[i] = i;
            }
            int extraEdge = 0;
            int count = 0;
            for(int[] edge:connections){
                int p = findParent(parent, edge[0]);
                int q = findParent(parent, edge[1]);
                if(p == q) extraEdge++; //有公共祖先,说明此条边多余,可以去掉
                else parent[q] = p; //如果没有,根据connections矩阵,将两个点连接起来
            }
            for(int i = 0; i < n; i++){
                if(parent[i] == i) count++; //计算有多少个祖先,即多少个 单独的联通量
            }
            return (extraEdge >= count-1) ? count-1 : -1;
        }
        public int findParent(int[] parent, int x){
            while(parent[x] != x){
                x = parent[x];
            }
            return x;
        }
    }
  • 相关阅读:
    CSS3 3D Transform
    js关闭当前页面(窗口)的几种方式总结
    JavaScript书籍阅读
    使用@media screen解决移动web开发的多分辨率问题
    ie678 兼容问题
    JS动态引入js,CSS——动态创建script/link/style标签
    扁平化设计的流行配色方案
    最简单的jquery轮播图
    ie7 z-index 失效问题
    js正则表达式手机号(邮箱)验证
  • 原文地址:https://www.cnblogs.com/yawenw/p/13038574.html
Copyright © 2011-2022 走看看