并查集模板题
这与前一个题目任意点几乎一样,只需要改一下main函数里面的一小部分代码就行
我们把联通之间的点放入一个集合,最后只需要去找根节点就知道有多少个集合,我们需要集合数减一的边就可以把这些散落的集合联系起来
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + 10; int pre[maxn]; int find(int x) //路径压缩 { if (x != pre[x]) pre[x] = find(pre[x]); return pre[x]; } void join(int x, int y) { int a = find(x); int b = find(y); if (a != b) pre[a] = b; } int main() { int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) //初始化 pre[i] = i; for (int i = 1; i <= m; ++i) { int x, y; scanf("%d%d", &x, &y); join(x, y); } int ans = 0; for (int i = 1; i <= n; ++i) if (pre[i] == i) ++ans; printf("%d\n", ans - 1); }