Connecting Cities With Minimum Cost

There are N cities numbered from 1 to N.

You are given connections, where each connections[i] = [city1, city2, cost] represents the cost to connect city1 and city2 together.  (A connection is bidirectional: connecting city1 and city2 is the same as connecting city2 and city1.)

Return the minimum cost so that for every pair of cities, there exists a path of connections (possibly of length 1) that connects those two cities together.  The cost is the sum of the connection costs used. If the task is impossible, return -1.

Example 1:

Input: N = 3, connections = [[1,2,5],[1,3,6],[2,3,1]]
Output: 6
Explanation: 
Choosing any 2 edges will connect all cities so we choose the minimum 2.

思路:可以用dijkstra来做,记住,建立图的时候,不能用hashmap<Integer, HashMap<Integer, Integer>> ,一定要用HashMap<Integer, List<Node>>来建立图,因为如果node与node之间有两条以上的path,hashmap会覆盖值,所以用list<Node>来包含所有边的情况;

class Solution {
    private class Node {
        public int city;
        public int cost;
        public Node(int city, int cost) {
            this.city = city;
            this.cost = cost;
        }
    }
    
    private class NodeComparator implements Comparator<Node> {
        @Override
        public int compare(Node a, Node b) {
            return a.cost - b.cost;
        }
    }
    
    public int minimumCost(int N, int[][] connections) {
        if(connections == null || connections.length == 0 || 
           connections[0].length == 0) {
            return -1;
        }
        // build graph;
        //     fromCity  List of (Node<toCity,cost>)
        HashMap<Integer, List<Node>> graph = new HashMap<>();
        for(int i = 1; i <= N; i++) {
            graph.putIfAbsent(i, new ArrayList<Node>());
        }
        
        for(int i = 0; i < connections.length; i++) {
            int fromcity = connections[i][0];
            int tocity = connections[i][1];
            int cost = connections[i][2];
            graph.get(fromcity).add(new Node(tocity, cost));
            graph.get(tocity).add(new Node(fromcity, cost));
        }
        
        HashSet<Integer> visited = new HashSet<Integer>();
        PriorityQueue<Node> pq = new PriorityQueue<Node>(N, new NodeComparator());
        pq.offer(new Node(1, 0));
        int count = 0;
        int totalcost = 0;
       
        while(!pq.isEmpty()) {
            Node head = pq.poll();
            int cost = head.cost;
            int city = head.city;
            if(visited.contains(city)) {
                continue;
            } 
            visited.add(city);
            totalcost += cost;
            count++;
            
            for(Node neighbor: graph.get(city)) {
                if(!visited.contains(neighbor.city)) {
                    pq.offer(neighbor);
                } 
            }
        }
        return count == N ? totalcost : -1;
    }
}

Minimum spanning Tree;可以sort每条边,然后每次用最小的边connect,用union find做

class Solution {
    private class UnionFind {
        private int[] father;
        private int count;
        public UnionFind(int n) {
            this.father = new int[n + 1];
            for(int i = 0; i <= n; i++) {
                father[i] = i;
            }
            this.count = n;
        }
        
        public int find(int x) {
            int j = x;
            while(father[j] != j) {
                j = father[j];
            }
            // path compression;
            while(j != x) {
                int fx = father[x];
                father[x] = j;
                x = fx;
            }
            
            return j;
        }
        
        public void union(int a, int b) {
            int root_a = find(a);
            int root_b = find(b);
            if(root_a != root_b) {
                father[root_a] = root_b;
                count--;
            }
        }
        
        public int getCount() {
            return this.count;
        }
    }
    
    private class connect {
        public int from;
        public int to;
        public int cost;
        public connect(int from, int to, int cost) {
            this.from = from;
            this.to = to;
            this.cost = cost;
        }
    }
    
    private class connectComparator implements Comparator<connect> {
        @Override
        public int compare(connect a, connect b) {
            return a.cost - b.cost;
        }
    }
    
    public int minimumCost(int N, int[][] connections) {
        if(connections == null || connections.length == 0 || connections[0].length == 0) {
            return -1;
        }
        PriorityQueue<connect> pq = new PriorityQueue(N, new connectComparator());
        for(int[] e : connections) {
            pq.add(new connect(e[0], e[1], e[2]));
        }
        
        UnionFind uf = new UnionFind(N);
        int totalcost = 0;
        while(!pq.isEmpty()) {
            connect con = pq.poll();
            int a = con.from;
            int b = con.to;
            if(uf.find(a) != uf.find(b)) {
                uf.union(a, b);
                totalcost += con.cost;
            }
        }
        
        if(uf.getCount() == 1) {
            return totalcost;
        } 
        return -1;
    }
}
发布了673 篇原创文章 · 获赞 13 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/u013325815/article/details/105174107