题目涉及到并查集的删点操作, 自己也是第一次接触, 看了一些题解, 有一些心得。
首先是不能简单地使用f[a] = a;来处理删点, 应该另外开一个数组idx表示一种映射状态, 也就是说我们每一次删除一个点, 就让idx[i] = n + num(num表示已经有得删点数量) 然后让f[n + num] = n + num; 就实现了f[idx[i]] = n + m的操作
代码:
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
using namespace std;
const int N = 1e06 + 10;
#define endl "\n"
int num, n, m;
int f[N], idx[N];
bool vis[N];
int find(int x) {
if (x != f[x]) f[x] = find(f[x]);
return f[x];
}
int main() {
int j = 1;
while (cin >> n >> m, n || m) {
for (int i = 0; i <= n - 1; i++) {
f[i] = idx[i] = i;
}
num = 0;
while (m--) {
string op;
cin >> op;
if (op == "M") {
int a, b;
cin >> a >> b;
a = find(idx[a]);
b = find(idx[b]);
if (a != b) {
f[a] = b;
}
} else {
int c;
cin >> c;
f[n + num] = n + num;
idx[c] = n + num;
num ++;
}
}
int res = 0;
memset(vis, false, sizeof vis);
for (int i = 0; i <= n - 1; i++) {
if (!vis[find(idx[i])]) {
res ++;
vis[find(idx[i])] = true;
}
}
/*for (int i = 0; i < n; i++) {
cout << find(idx[i]) << endl;
}*/
printf("Case #%d: %d\n", j, res);
j++;
}
return 0;
}

215

被折叠的 条评论
为什么被折叠?



