题目链接:https://leetcode.cn/problems/number-of-operations-to-make-network-connected/
题目大意:给出一个图,给出n
个点和若干条连接关系。可以进行一次操作【将一条边去掉,添加上另一条边】,求使得图连通的最小的操作次数。如果无法使得图连通,返回-1
思路:是一个连通分量问题,总之就是把所有连通分量整在一起。但这个“操作”有点吓到我了,一时没有头绪。看了题解后发现,其实可以逆向思维。
首先,想要n
个点连通,至少需要n-1
条边。那先使用并查集,假设所有的点一开始都是孤立的,需要的最小连接数为cnt = n-1
。随后遍历图的边,若两个点属于不同的并查集,那么将其连接。且因为这条边是题意给的,所以我们对这条被遍历的边【不用做操作】,因此cnt--
。
实际上这是在算【不用做操作】的次数,逆向来算,自减可以得到【需要做操作】的次数。
完整代码
class Solution {
public:
vector<int> fr;
int findRoot(int c) {
if (fr[c] != c)
return findRoot(fr[c]);
else
return c;
}
int makeConnected(int n, vector<vector<int>>& connections) {
int L = connections.size();
if (L < n-1)
return -1;
int cnt = n-1;
fr.resize(n);
iota(fr.begin(), fr.end(), 0);
for (int i = 0; i < L; i++) {
int c1 = connections[i][0], c2 = connections[i][1];
int r1 = findRoot(c1), r2 = findRoot(c2);
if (r1 != r2) {
fr[r2] = fr[r1];
cnt--;
}
}
return cnt;
}
};