【每日一刷】leetcode-1319. 连通网络的操作次数
用以太网线缆将 n 台计算机连接成一个网络,计算机的编号从 0 到 n-1。线缆用 connections 表示,其中 connections[i] = [a, b] 连接了计算机 a 和 b。
网络中的任何一台计算机都可以通过网络直接或者间接访问同一个网络中其他任意一台计算机。
给你这个计算机网络的初始布线 connections,你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。请你计算并返回使所有计算机都连通所需的最少操作次数。如果不可能,则返回 -1 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我们先明确边界条件:
回顾一下,如果想把n个节点连接起来,至少需要n-1条边,毕竟一条边只能联通两个点。
题目中又要求你可以拔开任意两台直连计算机之间的线缆,并用它连接一对未直连的计算机。
那么可以得出,当有n个节点(计算机)的时候,至少要给做n-1次操作,也就是说connections的大小至少是n-1,如果再小,就直接返回-1好了。看需求,题目要我们计算并返回使所有计算机都连通所需的最少操作次数
结合上面把n个节点连接起来,至少需要n-1条边的信息,如果我们再计算出这些connections已经把多少台计算机连接起来的信息后,就可以推算出使所有计算机都连通所需的最少操作次数了呢?
比如总共有十台机子,那么结合把n个节点连接起来,至少需要n-1条边,我们至少要9次操作,然后题目输入了一个长度为 X (X>=n-1) 的 connections,经过我们的计算已经连接上了7台机子,现在虽然进行了X次connections,但是有效的操作次数只有6次(因为连接了7台机子),所以还需要 9 - 6 = 3 次。
至此,题目就完了,至于计算出这些connections已经把多少台计算机连接起来的信息,可以通过使用并查集或者搜索来完成。并查集的介绍,可以在数据结构的系列文章中介绍一下~
附上代码:
class Solution { class unionSet { vector<int> father; public: int setCount = 0; unionSet(int n = 0) : father(n + 1) { for (int i = 1; i <= n; i++) father[i] = i; } int getFather(int x) { return father[x] = (father[x] == x ? x : getFather(father[x])); } void merge(int a, int b) { int aFather = getFather(a); int bFather = getFather(b); if (aFather == bFather) return ; ++setCount; father[aFather] = bFather; } }; public: int makeConnected(int n, vector<vector<int>>& connections) { if (connections.size() < n - 1) return -1; unionSet u(n); for (vector<int> &connection : connections) { u.merge(connection[0] + 1, connection[1] + 1); } return n - 1 - u.setCount; } };