トピック:
イーサネットケーブルを使用してn台のコンピューターをネットワークに接続します。コンピューター番号は0からn-1です。ケーブルは接続で表されます。ここで、connections [i] = [a、b]はコンピューターaとbを接続します。
ネットワーク内の任意のコンピューターは、ネットワークを介して同じネットワーク内の他のコンピューターに直接または間接的にアクセスできます。
このコンピュータネットワークの最初の配線接続を提供するために、直接接続されている2台のコンピュータ間のケーブルを抜き、それを使用して、直接接続されていないコンピュータのペアを接続できます。すべてのコンピューターを接続するために必要な最小操作数を計算して返します。それが不可能な場合は、-1が返されます。
入力:n = 4、接続= [[0,1]、[0,2]、[1,2]]
出力:1
説明:コンピューター1と2の間のケーブルを抜き、コンピューター1と3に差し込みます。オン。
入力:n = 6、接続= [[0,1]、[0,2]、[0,3]、[1,2]、[1,3]]
出力:2
例3:
入力:n = 6、接続= [[0,1]、[0,2]、[0,3]、[1,2]]
出力:-1
説明:ケーブルの数が不足しています。
例4:
入力:n = 5、接続= [[0,1]、[0,2]、[3,4]、[2,3]]
出力:0
コード
// 并查集模板
class UnionFind {
public:
vector<int> parent;
vector<int> size;
int n;
// 当前连通分量数目
int setCount;
public:
UnionFind(int _n): n(_n), setCount(_n), parent(_n), size(_n, 1) {
iota(parent.begin(), parent.end(), 0);
}
int findset(int x) {
return parent[x] == x ? x : parent[x] = findset(parent[x]);
}
bool unite(int x, int y) {
x = findset(x);
y = findset(y);
if (x == y) {
return false;
}
if (size[x] < size[y]) {
swap(x, y);
}
parent[y] = x;
size[x] += size[y];
--setCount;
return true;
}
bool connected(int x, int y) {
x = findset(x);
y = findset(y);
return x == y;
}
};
class Solution {
public:
int makeConnected(int n, vector<vector<int>>& connections) {
if (connections.size() < n - 1) {
return -1;
}
UnionFind uf(n);
for (const auto& conn: connections) {
uf.unite(conn[0], conn[1]);
}
return uf.setCount - 1;
}
};