最低成本联通所有城市【kruskal】【prim】
Kruskal
思路
贪心思想,将所有边进行排序,依次连接。利用UF判断亮点连通性,若2点已经连通,则跳过,避免成环。
实现
class Solution { public int minimumCost(int n, int[][] connections) { int cost = 0; Arrays.sort(connections, (x, y) -> x[2] - y[2]); UF uf = new UF(n); for (int[] connection: connections) { if (uf.conntected(connection[0] - 1, connection[1] - 1)) continue; cost += connection[2]; uf.union(connection[0] - 1, connection[1] - 1); } return uf.count() == 1? cost: -1; } } class UF { private int count; private int[] parent; public UF(int n) { count = n; parent = new int[n]; for (int i = 0; i < n; i++) parent[i] = i; } public void union(int p, int q) { int rootP = find(p); int rootQ = find(q); if (rootP == rootQ) return; parent[rootP] = rootQ; count--; } public boolean conntected(int p, int q) { return find(p) == find(q); } public int find(int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } public int count() { return count; } }
Prim
思路
每次将一个图切成2个连通分量,那么总有一条边是最小生成树的边。找到其中最小的边,加入即可。同时,将此边对应的新加入节点的边都加入候选。
为了避免成环,需要一个visited数组记录所有点的访问情况,若已访问则跳过。
实现
class Solution { public int minimumCost(int n, int[][] connections) { List<int[]>[] graph = buildGraph(n, connections); Prim prim = new Prim(graph); return prim.isAllConnected()? prim.minSum(): -1; } public List<int[]>[] buildGraph(int n, int[][] connections) { List<int[]>[] graph = new LinkedList[n]; for (int i = 0; i < n; i++) graph[i] = new LinkedList<>(); for (int[] connection: connections) { int from = connection[0] - 1; int to = connection[1] - 1; int cost = connection[2]; graph[from].add(new int[]{from, to, cost}); graph[to].add(new int[]{to, from, cost}); } return graph; } } class Prim { private PriorityQueue<int[]> pq; private boolean[] inMST; private int minSum = 0; private List<int[]>[] graph; public Prim(List<int[]>[] graph) { this.graph = graph; inMST = new boolean[graph.length]; pq = new PriorityQueue<>((x, y) -> x[2] - y[2]); inMST[0] = true; cut(0); while (!pq.isEmpty()) { int[] edeg = pq.poll(); int to = edeg[1]; int weight = edeg[2]; if (inMST[to]) continue; minSum += weight; inMST[to] = true; cut(to); } } public void cut(int n) { for (int[] edeg: graph[n]) { int to = edeg[1]; if (inMST[to]) continue; pq.offer(edeg); } } public int minSum() { return minSum; } public boolean isAllConnected() { for (boolean visited: inMST) { if (!visited) return false; } return true; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)