リンク:https://leetcode-cn.com/problems/number-of-operations-to-make-network-connected/
n
コンピュータをイーサネットケーブル でネットワークに接続すると、コンピュータ番号はからに 0
なり n-1
ます。ケーブルは 、コンピュータ と をconnections
示すために使用され ます 。connections[i] = [a, b]
a
b
ネットワーク内の任意のコンピューターは、ネットワークを介して同じネットワーク内の他のコンピューターに直接または間接的にアクセスできます。
このコンピュータネットワークの初期配線を行うために、 connections
直接接続されている2台のコンピュータ間のケーブルを抜き、それを使用して、直接接続されていないコンピュータのペアを接続できます。すべてのコンピューターを接続するために必要な最小操作数を計算して返します。それが不可能な場合は、-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]
- 重複する接続はありません。
- 2台のコンピューターを複数のケーブルで接続することはありません。
アイデア:n個のポイントを相互に接続する必要があり、最小のエッジはn-1であり、ツリー構造を形成します。この質問では、各連結成分を点として扱い、グラフにx個の連結成分があると仮定すると、x-1個のエッジのみが必要になります。ユニオン検索を使用して、接続された各コンポーネントの冗長エッジの数を見つけることができます。
class Solution {
public:
int Father[100010];
unordered_set<int> Root;
int Find(int x){
return x == Father[x] ? x : Father[x] = Find(Father[x]);
}
bool Union(int A,int B){
A = Find(A);
B = Find(B);
if(A != B){
Father[A] = B;
Root.erase(A);
return true;
}
return false;
}
int makeConnected(int n, vector<vector<int>>& connections) {
int m = connections.size(), i, reseEdges = 0;
if(m < n - 1) return -1; // 最少需要的边数 == n - 1
for(i = 0; i < n; ++ i){
Father[i] = i;
Root.insert(i);
}
for(i = 0; i < m; ++ i){
if(!Union(connections[i][0],connections[i][1])){
++ reseEdges;
}
}
return reseEdges >= Root.size() - 1 ? Root.size() - 1 : -1;
}
};