SPOJ - JMFILTER - Junk-Mail Filter

题目链接:SPOJ - JMFILTER - Junk-Mail Filter


题意很明显,就是维护一个带删除的并查集。

如果跟以往一样 f[x]=x,的初始化,那么如果删除的点是根节点就很麻烦,所以我们对每个点建立一个新的父亲节点,每次删除的时候,改变父亲节点即可。


AC代码:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e6+10;
int n,m,res,ts;
int f[N],id[N],vis[N],cnt;	char op[5];
inline int read(){
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void init(){
	memset(vis,0,sizeof vis);	res=0;	cnt=n;
	for(int i=1;i<=n;i++)	f[i]=id[i]=i;
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
inline void merge(int x,int y){f[find(id[x])]=find(id[y]);}
inline void del(int x){id[x]=++cnt; f[cnt]=cnt;}
inline void solve(){
	init();
	for(int i=1,x,y;i<=m;i++){
		scanf("%s",op);
		if(op[0]=='M')	x=read()+1,y=read()+1,merge(x,y);
		else	x=read()+1,del(x);
	}
	for(int i=1,x;i<=n;i++)	if(!vis[x=find(id[i])])	res++,vis[x]=1;
	printf("Case #%d: %d\n",++ts,res);
}
signed main(){
	while(cin>>n>>m,n+m)	solve();
	return 0;
}
发布了725 篇原创文章 · 获赞 244 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/104697698