ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

最低成本联通所有城市(Kruskal)

2021-10-21 23:32:30  阅读:310  来源: 互联网

标签:联通 weight int Kruskal 最低 edge new public size


想象一下你是个城市基建规划者,地图上有 N 座城市,它们按以 1 到 N 的次序编号。

给你一些可连接的选项 conections,其中每个选项 conections[i] = [city1, city2, cost] 表示将城市 city1 和城市 city2 连接所要的成本。(连接是双向的,也就是说城市 city1 和城市 city2 相连也同样意味着城市 city2 和城市 city1 相连)。

返回使得每对城市间都存在将它们连接在一起的连通路径(可能长度为 1 的)最小成本。该最小成本应该是所用全部连接代价的综合。如果根据已知条件无法完成该项任务,则请你返回 -1。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/connecting-cities-with-minimum-cost
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。


方向不敏感

每次选择最短的边

时间复杂度:O(eloge)

import java.util.*;

public class Solution {
    public static int minimumCost(int n, int[][] connections) {
        Graph graph = new Graph();
        Union union = new Union(n);
        for (int i = 0; i < connections.length; ++i) {
            graph.addEdge(connections[i][0], connections[i][1], connections[i][2]);

        }
        List<Edge> edges = graph.getEdges();
        PriorityQueue<Edge> queue = new PriorityQueue<Edge>(new Comparator<Edge>() {
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.weight - o2.weight;
            }
        });
        queue.addAll(edges);
        Set<Edge> resSet = new HashSet<Edge>();
        while (!queue.isEmpty()) {
            Edge edge = queue.poll();
            if (!union.inSameSet(edge.from.value, edge.to.value)) {
                resSet.add(edge);
                union.union(edge.from.value, edge.to.value);
            }
        }
        if (union.size() != 1) {
            return -1;
        } else {
            return resSet.stream().mapToInt(edge -> edge.weight).sum();
        }
    }

    public static void main(String[] args) {
        int n = 3;
        int[][] arr = {
                {1, 2, 5}, {1, 3, 6}, {2, 3, 1}
        };
        System.out.println(minimumCost(n, arr));
    }
}

class Graph {

    private Map<Node, Map<Node, Edge>> edgeMap = new HashMap<>();

    private Map<Integer, Node> nodes = new HashMap<>();

    private List<Edge> edges = new ArrayList<>();

    public List<Edge> getEdges() {
        return edges;
    }

    public Map<Integer, Node> getNodes() {
        return nodes;
    }

    /**
     * 如果边不存在,则创建边,同时保留最优边
     *
     * @param from
     * @param to
     * @param weight
     * @return
     */
    private Edge buildEdge(Node from, Node to, int weight) {
        Map<Node, Edge> fromMap = edgeMap.computeIfAbsent(from, k -> new HashMap<>());
        Edge edge = fromMap.get(to);
        // 新边
        if (edge == null) {
            edge = new Edge(from, to, weight);
            fromMap.put(to, edge);
            from.edges.add(edge);
            edges.add(edge);
        } else {
            // 留下最优边
            if (edge.weight > weight) {
                edge.weight = weight;
            }
        }
        return edge;
    }

    /**
     * 如果不存在,则创建节点
     *
     * @param index
     * @return
     */
    private Node buildNode(int index) {
        Node node = nodes.get(index);
        if (node == null) {
            node = new Node(index);
            nodes.put(index, node);
        }
        return node;
    }

    /**
     * 添加边
     *
     * @param fromIndex
     * @param toIndex
     * @param weight
     */
    public void addEdge(int fromIndex, int toIndex, int weight) {
        buildEdge(buildNode(fromIndex), buildNode(toIndex), weight);
    }
}

class Edge {
    Node from;
    Node to;
    int weight;

    public Edge(Node from, Node to, int weight) {
        this.from = from;
        this.to = to;
        this.weight = weight;
    }
}

class Node {
    int value;
    int in;
    int out;
    List<Edge> edges;

    public Node(int value) {
        this.value = value;
        this.in = 0;
        this.out = 0;
        this.edges = new ArrayList<>();
    }
}

class Union {
    private int[] parent;
    private int[] size;

    public Union(int n) {
        this.parent = new int[n + 1];
        this.size = new int[n + 1];
        for (int i = 1; i <= n; ++i) {
            parent[i] = i;
            size[i] = 1;
        }
    }

    public int find(int x) {
        int p = parent[x];
        if (p == x) {
            return p;
        }
        p = find(p);
        parent[x] = p;
        return p;
    }

    public void union(int a, int b) {
        int p1 = find(a);
        int p2 = find(b);
        if (p1 == p2) {
            return;
        }

        if (size[p1] >= size[p2]) {
            parent[p2] = p1;
            size[p1] = size[p1] + size[p2];
            size[p2] = 0;
        } else {
            parent[p1] = p2;
            size[p2] = size[p1] + size[p2];
            size[p1] = 0;
        }
    }

    public boolean inSameSet(int a, int b) {
        return find(a) == find(b);
    }

    public int size() {
        int sum = 0;
        for (int i = 0; i < size.length; ++i) {
            if (size[i] > 0) {
                sum++;
            }
        }
        return sum;
    }
}

标签:联通,weight,int,Kruskal,最低,edge,new,public,size
来源: https://www.cnblogs.com/tianyiya/p/15436838.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有