题意:
典型并查集的操作 合并两个点 从指定的集合中删去一个点 询问当前集合的个数
题解:
建立虚拟点,当点被孤立的时候,该点对应的点变化,即可模拟孤立点,后续关于该点的建立集合以新点为目标
#include <iostream>
#include <set>
using namespace std;
const int maxn = 1e6*2+5;
int f[maxn],id[maxn];
int find(int x){
return f[x]==x?x:f[x]=find(f[x]);
}
void join(int x,int y){
int X = find(id[x]);
int Y = find(id[y]);
if(X!=Y)
f[X] = Y;
}
set<int> S;
int main(){
int n,m,a,b;
int kase = 0;
while(scanf("%d%d",&n,&m)){
if(n==0&&m==0) break;
int cnt = n;
for(int i=0;i<n+m;i++){
f[i] = i;
}
for(int i=0;i<n;i++){
id[i] = i;
}
//cout<<find(2)<<endl;
char s[5];
while(m--){
scanf("%s",s);
if(s[0]=='M'){
scanf("%d%d",&a,&b);
int X = find(id[a]);
int Y = find(id[b]);
if(X!=Y)
f[X] = Y;
//cout<<find(id[a])<<" "<<find(id[b])<<endl;
}else{
scanf("%d",&a);
id[a] = cnt++;
}
}
S.clear();
for(int i=0;i<n;i++){
//cout<<id[i]<<endl;
S.insert(find(id[i]));
}
printf("Case #%d: %d\n",++kase,S.size());
}
return 0;
}