HDU2473 Junk-Mail Filter 并查集

欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - HDU2473


题意概括

  一堆点。

  要你支持合并两组点、分离某组点中的一个,这两种操作。

  点数<=100000,操作数<=1000000


题解

  删除点不难,只需要把之前那个点不删除,然后再建立一个新的点就可以了。具体直接看代码应该就懂了。


代码

#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <cmath>
using namespace std;
const int N=100005,M=1000005;
int Case=0,n,m,fa[N+M],last[N],cnt;
int res[N];
int getf(int k){
	return fa[k]==k?k:fa[k]=getf(fa[k]);
}
int main(){
	while (~scanf("%d%d",&n,&m)&&(n||m)){
		for (int i=1;i<=n;i++)
			last[i]=fa[i]=i;
		cnt=n;
		while (m--){
			char op[2];
			int a,b;
			scanf("%s",op);
			if (op[0]=='M'){
				scanf("%d%d",&a,&b);
				a++,b++;
				a=getf(last[a]),b=getf(last[b]);
				fa[a]=b;
			}
			else {
				scanf("%d",&a);
				a++;
				last[a]=++cnt;
				fa[cnt]=cnt;
			}
		}
		for (int i=1;i<=n;i++)
			res[i]=getf(last[i]);
		sort(res+1,res+n+1);
		int ans=1;
		for (int i=2;i<=n;i++)
			if (res[i]!=res[i-1])
				ans++;
		printf("Case #%d: %d
",++Case,ans);
	}
	return 0;
} 

  

原文地址:https://www.cnblogs.com/zhouzhendong/p/HDU2473.html