lintcode 3672 · 最低成本联通所有城市【中等】

文章介绍了如何使用并查集数据结构解决给定城市间连接问题,计算将所有城市连通所需的最低成本,若无法全部连通则返回-1。通过排序连接数组按成本升序,利用并查集实现快速查找和合并操作。
摘要由CSDN通过智能技术生成

题目链接、描述

https://www.lintcode.com/problem/3672

在本题中共存在 n 个城市,其编号范围为 1 到 n。

同时存在一个 connections 数组且 connections[i] = [a_i, b_i, c_i]connections[i]=[a_i
,b_i ,c_i ],其含义为联通城市 a_i 和 b_i 的成本为 c_i
请返回连通全部城市所需要的最低成本。如果无法联通全部城市,返回 -1。


样例
样例 1

输入:

3
[[1,2,1], [2,3,2], [1,3,3]]
输出:

3
解释:

选择 [1,2,1][2,3,2] 即可联通全部 n 个城市,此时花费最少,为 3。

样例 2

输入:

3
[[1,2,1]]
输出:

-1
解释:

无法根据 connections 联通所有的城市。

思路

并查集

答案

public class Solution {
    /**
     * @param n: the number of cities
     * @param connections: the connection info between cities
     * @return: nothing
     */
    public int minimumCost(int n, int[][] connections) {
         Arrays.sort(connections, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                return a[2] - b[2];
            }
        });

        UF uf = new UF(n);
        int ans = 0;
        for (int[] arr : connections) {
            int a = arr[0], b = arr[1], cost = arr[2];
            int f1 = uf.find(a);
            int f2 = uf.find(b);
            if (f1 == f2) continue;
            ans += cost;
            uf.union(a, b);
            if (uf.sets == 1) return ans;
        }
        return -1;
    }

    static class UF {
        int[] parents;
        int[] size;
        int[] help;
        int sets;

        public UF(int n) {
            sets = n;
            parents = new int[n + 1];
            size = new int[n + 1];
            help = new int[n + 1];
            for (int i = 1; i <= n; i++) {
                parents[i] = i;
                size[i] = 1;
            }
        }

        public int find(int x) {
            int hi = 0;
            while (x != parents[x]) {
                help[hi++] = x;
                x = parents[x];
            }
            for (hi--; hi >= 0; hi--) {
                parents[help[hi]] = x;
            }
            return x;
        }

        public void union(int a, int b) {
            int f1 = find(a);
            int f2 = find(b);
            if (f1 != f2) {
                if (size[f1] >= size[f2]) {
                    size[f1] += size[f2];
                    parents[f2] = f1;
                } else {
                    size[f2] += size[f1];
                    parents[f1] = f2;
                }
                sets--;
            }
        }
    }


}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵长辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值