版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82714210
解析:
用一个 数组表示当前节点在并查集中的对应节点编号。
删除的时候直接更改节点 值就行了。
还有。
为什么
是关键字啊!!!
为什么
下标强制从0开始啊???
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
#define rank Rank
inline
ll getint(){
re ll num=0;
re char c;
while(!isdigit(c=gc()));
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=gc();
return num;
}
inline
void outint(ll a){
static char ch[23];
if(a==0)pc('0');
while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
while(ch[0])pc(ch[ch[0]--]);
}
inline char getalpha(){
re char c;
while(!isalpha(c=gc()));
return c;
}
int n,m;
int pos[100002],tot;
int fa[1100002];
int rank[1100002];
bool vis[1100002];
inline
int getfa(int x){
return x==fa[x]?x:fa[x]=getfa(fa[x]);
}
inline
void merge(int i,int j){
i=getfa(i),j=getfa(j);
if(i==j)return ;
if(rank[i]>rank[j])swap(i,j);
fa[j]=i;
if(rank[i]==rank[j])++rank[i];
}
int tt;
signed main(){
while(n=getint(),m=getint(),n+m){
++tt;
memset(rank,0,sizeof rank);
memset(vis,0,sizeof vis);
for(int re i=0;i<n;++i)fa[i]=i,pos[i]=i;
tot=n-1;
while(m--){
char op=getalpha();
switch(op){
case 'M':{
int x=getint(),y=getint();
merge(pos[x],pos[y]);
break;
}
case 'S':{
int x=getint();
fa[pos[x]=++tot]=tot;
break;
}
}
}
int ans=0;
for(int re i=0;i<n;++i)if(!vis[getfa(pos[i])])++ans,vis[getfa(pos[i])]=true;
printf("Case #%d: %d\n",tt,ans);
}
return 0;
}