看了别人的代码算是学到了如何实现并查集的删除,也就是把被删除节点保持不动,继续作为其他点查找的桥梁,然后为该节点重新设置新的节点,在纸上模拟下该过程大概就能懂了
#include<iostream>
#include<cstring>
#define maxn 1000000+5
using namespace std;
string cmd;
int n,m,replace;
int f[maxn],g[maxn],sign[maxn];
void ready()
{
for(int i=0;i<n;i++) f[i]=g[i]=i;
memset(sign,0,sizeof(sign));//不能只初始到n就结束
}
int dfs(int x)
{
if(f[x]!=x) f[x]=dfs(f[x]);
return f[x];
}
void build(int x,int y)
{
if(dfs(x)!=dfs(y)) f[dfs(x)]=dfs(y);
}
void de(int x)
{
f[replace]=replace;//新节点的初始化
g[x]=replace++;
}
int main()
{
int casee=1;
while(cin>>n>>m&&(m||n))
{
ready();
replace=n;
int x,y;
while(m--)
{
cin>>cmd;
if(cmd=="M") cin>>x>>y,build(g[x],g[y]);
else cin>>x,de(x);
}
int sum=0;
for(int i=0;i<n;i++)
{
if(!sign[dfs(g[i])]) sum++,sign[dfs(g[i])]=1;
}
cout<<"Case #"<<casee++<<": "<<sum<<endl;
}
return 0;
}