题解 | JAVA Prim/Kruskal #最小生成树# [P3-T1]

最小生成树

http://www.nowcoder.com/practice/735a34ff4672498b95660f43b7fcd628

Prim和Kruskal两种方法
// Prim
// Time: O(MlogM), each edge is inserted to minHeap once.
// Spcae: O(n)
import java.util.*;

public class Solution {
    public int miniSpanningTree (int n, int m, int[][] cost) {
      // u -> [[v1, c1], [v2, c2], ...]
      List<List<int[]>> graph = new ArrayList<>();
      for (int i = 0; i <= n; i++) graph.add(new ArrayList<>());  // 0 is dummy
      for (int[] c : cost) {
        graph.get(c[0]).add(new int[]{c[1], c[2]});
        graph.get(c[1]).add(new int[]{c[0], c[2]});
      }
      
      // [u, v, cost]
      PriorityQueue<int[]> minEdgeHeap = new PriorityQueue<>((a,b)->a[2]-b[2]);
      for (int[] edges : graph.get(1)) {  // add all edges connecting 1
        minEdgeHeap.offer(new int[]{1, edges[0], edges[1]});
      }
      
      boolean[] visited = new boolean[n+1];
      visited[1] = true;  // mark 1 as visited
      
      int totalCost = 0;
      while (!minEdgeHeap.isEmpty()) {
        int[] minEdge = minEdgeHeap.poll();
        int from = minEdge[0], to = minEdge[1], c = minEdge[2];
        if (visited[to]) continue;  // already in MST
        visited[to] = true;
        totalCost += c;
          
        for (int[] nei : graph.get(to)) {
          if (visited[nei[0]]) continue;  // neighbor alrady in MST
          minEdgeHeap.offer(new int[]{to, nei[0], nei[1]});
        }
      }
      
      return totalCost;
    }
}
// Krsukal
// Time: O(MlogM + M) = O(MLogM)
//    sort M edges takes MlogM, union N nodes takes ~O(M)
// Space: O(N)
import java.util.*;

public class Solution {
    class DSU {
      int[] rank; 
      int[] root; 
      
      DSU(int size) {
        this.rank = new int[size];
        this.root = new int[size];
        for (int i = 0; i < size; i++) {
          this.root[i] = i;  // init with self as parent
        }
      }
      
      // find with path compression
      int findRoot(int id) {
        if (root[id] != id) {
          root[id] = findRoot(root[id]); 
        }
        return root[id];
      }
      
      // union by rank
      void union(int id_a, int id_b) {
        int root_a = findRoot(id_a);
        int root_b = findRoot(id_b);
        if (rank[root_a] == rank[root_b]) {
          root[root_b] = root_a;
          rank[root_a]++;
        } else if (rank[root_a] > rank[root_b]){
          root[root_b] = root_a;
        } else {
          root[root_a] = root_b;
        }
      }
    }
    
    public int miniSpanningTree (int n, int m, int[][] cost) {
      DSU dsu = new DSU(n);
      Arrays.sort(cost, (a, b) -> a[2] - b[2]);

      int minCost = 0;
      for (int[] c : cost) {
        // nodes are indexed from 1 to n, so need to minus 1
        int root_a = dsu.findRoot(c[0]-1);
        int root_b = dsu.findRoot(c[1]-1);
        if (root_a == root_b) continue;  // already connected
        
        dsu.union(root_a, root_b);
        minCost += c[2];
      }
      
      return minCost;
    }
}
全部评论

相关推荐

就前几天旅游的时候,打开抖音就经常刷到这类视频:以前是高学历学生、老师、主持人,现在做着团播、擦边主播的工作,以及那些经过精心包装的“职业转型”故事——从铺天盖地的VLOG到所谓的“04年夜场工作日记”,这些内容在初中升学、高考放榜等关键时间节点持续发酵。可以说非常直接且精准地在潜移默化地影响着心智尚未成熟的青少年,使其对特殊行业逐渐脱敏。那我就想问了:某些传播公司、平台运营者甚至某些夜场的老板,你们究竟在传递怎样的价值观?点开那些视频,评论区里也是呈现明显的两极分化:一种是​​经济下行论​​:“现在就业市场已经艰难到这种程度了吗?”​​一种是事实反驳派​​:这些创作者往往拥有名校背景,从事着...
牛客刘北:被环境教育的,为了能拿到足够的钱养活自己,不甘心也得甘心,现在的短视频传播的思想的确很扭曲,但是很明显,互联网玩上一年你就能全款提A6,但你全心全意不吃不喝工作一年未必能提A6,但是在高考中考出现这个的确很扭曲,在向大家传播“不上学,玩互联网也可以轻松年入百万”,不是人变了,是社会在变
预测一下26届秋招形势
点赞 评论 收藏
分享
06-04 09:27
门头沟学院 Java
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-07 14:00
点赞 评论 收藏
分享
评论
3
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务