Junk-Mail Filter

Posted yeah17981

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Junk-Mail Filter相关的知识,希望对你有一定的参考价值。

最近在给新生上数据结构

于是复习(预习)了一下并查集

怎么有人给别人上课前才在学啊

(去年学了,但是摸太久了忘了)

给n个点m条操作

操作M:认为a和b属于一个集合

操作S:认为a不属于原来的集合

求有多少个集合

很明显是并查集

但是多了个删除单点的操作

设置虚拟节点

若原本1,2,3属于一个集合,设置一个虚拟节点5,原本123都指向5,现在使1出集合,就将1指向6

#include<bits/stdc++.h>
using namespace std;
const int N=1e5;
int par[N]; //存储每个点的祖宗节点
int rank[N]; //树的高度
// 返回x的祖宗节点
int f[N];
void init(int n,int m)

	for (int i = 0; i <n; i ++ ) 
	
		par[i] = i+n;// 初始化
		//rank[i]=0;
		f[i]=0;
	
	for (int i = n; i <=n+n+m; i ++ ) 
	
		par[i] = i;// 初始化
		//rank[i]=0;
		f[i]=0;
	

int find(int x)

    if (par[x] == x) 
	
		return x;
	
	else
	
		return par[x]=find(par[x]);
	

void unite(int x,int y)

	x=find(x);
	y=find(y);
	if(x==y) return ;
	par[x]=y;
//	if(rank[x]<rank[y])
//	
//		par[x]=y;
//	
//	else
//	
//		par[y]=x;
//		if(rank[x]==rank[y])return rank[x]++;
//	


bool same(int x,int y)

	return find(x)==find(y);

int main()

	int n,m;
	
	int a,b;
	char k;
		int cot=0;
	while(cin>>n>>m)
		
	if(n==0) break;
		init(n,m); 
		int z=n+n;
		for(int i=1;i<=m;i++) 
		
			cin>>k;
			if(k=='M')
			
			cin>>a>>b;
			// 合并a和b所在的两个集合:
			par[find(a)] = find(b);	
		
		else
		
			cin>>a;
			par[a]=z;
			z++;
		
		
		int tot=0;
		for(int i=0;i<n;i++) 
		
			if(f[find(i)]==0)
			
				f[find(i)]=1;
				tot++;
			
		

		printf("Case #%d: %d\\n",++cot,tot);
	
	
  

以上是关于Junk-Mail Filter的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2473 Junk-Mail Filter (并查集的删除操作)

HDU 2473 Junk-Mail Filter 并查集删除

hdu 2473 Junk-Mail Filter 并查集删点,模板题

Junk-Mail Filter

HDU 2473 Junk-Mail Filter 删点并查集

[HDOJ2473]Junk-Mail Filter(并查集,删除操作,马甲)