package com.heu.wsq.leetcode.bingchaji;
/**
* 1319. 连通网络的操作次数
* @author wsq
* @date 2021/1/23
* 用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。
* 网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。
* 给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。
*
* 示例 1:
* 输入:n = 4, connections = [[0,1],[0,2],[1,2]]
* 输出:1
* 解释:拔下计算机 1 和 2 之间的线缆,并将它插到计算机 1 和 3 上。
*
* 链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected
*/
public class MakeConnected {
public int makeConnected(int n, int[][] connections){
int m =connections.length;
if (m < n - 1){
return -1;
}
UnionFind unionFind = new UnionFind(n);
for (int[] connection : connections) {
unionFind.union(connection[0], connection[1]);
}
/**
* 这部分统计放在并查集中
* Set<Integer> set = new HashSet<>();
* for (int i = 0; i < n; i++){
* int rootX = unionFind.find(i);
* set.add(rootX);
* }
*/
return unionFind.setCount - 1;
}
private class UnionFind{
private int[] parent;
/**
* 连通分量数目
*/
private int setCount;
public UnionFind(int n){
parent = new int[n];
setCount = n;
for (int i = 0; i < n; i++) {
this.parent[i] = i;
}
}
public void union(int x, int y){
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY){
return;
}
this.parent[rootX] = rootY;
--setCount;
}
public int find(int x){
if (x != this.parent[x]){
this.parent[x] = find(this.parent[x]);
}
return this.parent[x];
}
public boolean isConnected(int x, int y){
return find(x) == find(y);
}
public int getSetCount(){
return this.setCount;
}
}
}