hdu2473 Junk-Mail Filter (并查集删除节点)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2473


题解:为每一个结点加一个虚根,这样每个结点都是叶子结点.插入结点时,把它们都并到虚根的集合中.删除结点时,只要把它的父结点置为一个无用的虚根。


#include <stdio.h>
#include <string.h>
#define MAXN 1000002

int father[MAXN<<1],flag[MAXN];

int Scan()  
{  
	int res = 0, ch, flag = 0;  
	if((ch = getchar()) == '-')   
		flag = 1;  
	else if(ch >= '0' && ch <= '9') 
		res = ch - '0';  
	while((ch = getchar()) >= '0' && ch <= '9' )  
		res = res * 10 + ch - '0';  
	return flag ? -res : res;  
}  

int find(int x)
{
	int i,j,r;
	r=x;
	while(r!=father[r])
		r=father[r];    
	i=x;
	while(i!=r)
	{    
		j=father[i];    
		father[i]=r;    
		i=j;    
	}
	return r;
}

void Union(int x,int y)    
{    
	int fx=find(x);    
	int fy=find(y);    
	if (fx!=fy)    
	{    
		father[fx]=fy;    
	}     
}

void init(int n,int m)
{
	int i,MAX;
	MAX=n+n+m;
	for(i=0;i<n;++i)
		father[i]=i+n;
	for(i=n;i<MAX;++i)
		father[i]=i;
}

int main()
{
	int n,m,ans,i,id,x,y,cases=1;
	char ch[5];
	while(scanf("%d %d",&n,&m)&&(m+n)!=0)
	{
		init(n,m);
		id=n+n;
		for(i=0;i<m;++i)
		{
			scanf("%s",ch);
			if(ch[0]=='M')
			{
				x=Scan();
				y=Scan();
				Union(x,y);
			}
			else
			{
				x=Scan();
				father[x]=id++;
			}
		}
		memset(flag,0,sizeof(flag));
		ans=0;
		for(i=0;i<n;++i)
		{
			x=find(i);
			if(!flag[x])
			{
				ans++;
				flag[x]=1;
			}
		}
		printf("Case #%d: %d\n",cases++,ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值