侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 675 篇文章
  • 累计创建 128 个标签
  • 累计收到 26 条评论

目 录CONTENT

文章目录

【图, 并查集】连通网络的操作次数

GabrielxD
2022-05-23 / 0 评论 / 0 点赞 / 277 阅读 / 683 字
温馨提示:
本文最后更新于 2022-07-26,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

1319. 连通网络的操作次数


用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 ab

网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。

给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。

示例 1:

image-20220523190307197

输入:n = 4, connections = [[0,1],[0,2],[1,2]]
输出:1
解释:拔下计算机 1 和 2 之间的线缆,并将它插到计算机 1 和 3 上。

示例 2:

image-20220523190315886

输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2],[1,3]]
输出:2

示例 3:

输入:n = 6, connections = [[0,1],[0,2],[0,3],[1,2]]
输出:-1
解释:线缆数量不足。

示例 4:

输入:n = 5, connections = [[0,1],[0,2],[3,4],[2,3]]
输出:0

提示:

  • 1 <= n <= 10^5
  • 1 <= connections.length <= min(n*(n-1)/2, 10^5)
  • connections[i].length == 2
  • 0 <= connections[i][0], connections[i][1] < n
  • connections[i][0] != connections[i][1]
  • 没有重复的连接。
  • 两台计算机不会通过多条线缆连接。

解题

方法一:并查集

思路

当计算机的数量为 n 时,至少需要 n-1 根线才能将它们进行连接。如果线的数量少于 n-1,无论如何都无法将这 n 台计算机进行连接。因此如果 connections 的长度小于 n-1,直接返回 -1 作为答案,否则一定可以找到一种操作方式将所有计算机进行连接。

把所有电脑看成一个图,这个图的连通分量减去连接最多电脑的一个子图就是可以找到的使所有计算机都连通所需的最少操作次数。使用并查集算出这个图的连通分量,减一返回即可。

代码

class Solution {
    private int[] unionFind;

    public int makeConnected(int n, int[][] connections) {
        if (connections.length < n - 1) return -1;
        unionFind = new int[n];
        for (int i = 0; i < n; i++) unionFind[i] = i;
        for (int[] connection : connections) union(connection[0], connection[1]);
        int count = 0;
        for (int i = 0; i < n; i++) {
            if (i == unionFind[i]) count++;
        }
        return count - 1;
    }

    private void union(int p, int q) {
        unionFind[find(p)] = find(q);
    }

    private int find(int n) {
        if (n != unionFind[n]) unionFind[n] = find(unionFind[n]);
        return unionFind[n];
    }
}
0

评论区