用以太网线缆将 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 上。
示例 2:
输入: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]
没有重复的连接。
两台计算机不会通过多条线缆连接。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
又是熟悉的并查集操作,如果明白并查集原理的朋友真的是手到擒来,解题关键有两点,第一如果线的数量不够则不可能连通,第二需要最小的操作次数是连通图的个数-1,连通图通过并查集很快就能够找到,详细的注解已经在代码中,这里不够多赘述了,代码如下:
class Solution {
public:
int makeConnected(int n, vector<vector<int>>& connections) {
// 线的数目
int size = connections.size();
// 统计连通图的数目
int num = 0;
// 如果线的数量不够
if(size < n - 1){
return -1;
}
vector<int> parent(n);
// 初始化
for(int i = 0; i < n; i ++) {
parent[i] = i;
}
// 并查集
for(int i = 0; i < size; i ++) {
int a = connections[i][0];
int b = connections[i][1];
unionFind(parent, a, b);
}
unordered_map<int, int> mp;
for(int i = 0; i < n; i ++){
mp[find(parent, i)] ++;
}
// 统计连通图的数量
for(auto p : mp){
num ++;
}
return num - 1;
}
// 查找祖宗
int find(vector<int>& parent, int i) {
if(parent[i] != i){
parent[i] = find(parent, parent[i]);
}
return parent[i];
}
// 合并节点
void unionFind(vector<int>&parent, int a, int b) {
parent[find(parent, a)] = find(parent, b);
}
};
/*作者:heroding
链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/solution/cbing-cha-ji-ji-bai-99-by-heroding-8wun/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。*/