• 图-最小生成树-629. 最小生成树


    2020-03-14 12:22:08

    问题描述:

    给出一些Connections,即Connections类,找到一些能够将所有城市都连接起来并且花费最小的边。
    如果说可以将所有城市都连接起来,则返回这个连接方法;不然的话返回一个空列表。

    样例

    样例 1:

    输入:
    ["Acity","Bcity",1]
    ["Acity","Ccity",2]
    ["Bcity","Ccity",3]
    输出:
    ["Acity","Bcity",1]
    ["Acity","Ccity",2]
    

    样例 2:

    输入:
    ["Acity","Bcity",2]
    ["Bcity","Dcity",5]
    ["Acity","Dcity",4]
    ["Ccity","Ecity",1]
    输出:
    []
    解释:
    没有办法连通
    

    注意事项

    返回按cost排序的连接方法,如果cost相同就按照city1进行排序,如果city1也相同那么就按照city2进行排序。

    问题求解:

    最小生成树模版题,采用的是kruskal算法。需要注意的是在最后需要对并查集进行校验,如果只有一个root,才能返回,否则就是森林,图无法连通。

    时间复杂度:O(nlogn)

        Map<String, String> parent = new HashMap<>();
        public List<Connection> lowestCost(List<Connection> connections) {
            // Write your code here
            List<Connection> res = new ArrayList<>();
            int n = connections.size();
            Collections.sort(connections, new Comparator<Connection>(){
                public int compare(Connection o1, Connection o2) {
                    if (o1.cost != o2.cost) {
                        return Integer.compare(o1.cost, o2.cost);
                    }
                    else if (!o1.city1.equals(o2.city1)) {
                        return o1.city1.compareTo(o2.city1);
                    }
                    else return o1.city2.compareTo(o2.city2);
                }
            });
            for (int i = 0; i < n; i++) {
                Connection e = connections.get(i);
                if (union(e.city1, e.city2)) res.add(e);
            }
            int cnt = 0;
            for (String key : parent.keySet()) {
                if (parent.get(key).equals(key)) cnt += 1;
            }
            if (cnt > 1) return new ArrayList<>();
            return res;
        }
        
        private String find(String node) {
            if (!parent.containsKey(node)) parent.put(node, node);
            if (!parent.get(node).equals(node)) {
                parent.put(node, find(parent.get(node)));
            }
            return parent.get(node);
        }
        
        private boolean union(String s1, String s2) {
            String p1 = find(s1);
            String p2 = find(s2);
            if (p1.equals(p2)) return false;
            parent.put(p1, p2);
            return true;
        }
    

      

  • 相关阅读:
    Ubuntu查看端口占用情况
    在jupyter中添加新的环境
    C++指针
    C++排序:冒泡排序,简单选择排序,直接插入排序,希尔排序,堆排序,归并排序,快速排序
    查找一:C++静态查找
    C++链式队列
    C++顺序循环队列
    C++链式栈
    C++顺序栈
    C++双向循环链表
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12491503.html
Copyright © 2020-2023  润新知