UVA - 11987 Almost Union-Find(并查集)

题意是需要写一个不相交集,有三种操作,第一种是,把包含片p和q元素的集合合并,如果p、q在同一集合,则忽视这个操作

第二种操作是把p加入到q所在的集合,如果p、q在同一集合,则忽视这个操作

第三中操作,输出p所在集合的元素个数与元素和。


第一种操作直接用并查集的合并即可,第三中操作用一个sum数组和size数组储存即可。

麻烦的是第二种操作,直接合并p和q的话是不可取的,需要把这个p从原有集合中删除,然后把这个点的信息插入末尾,此时需要一个数组real来存储所有元素的真实编号,然后在与q合并。


#include<stdio.h>
int pre[200002];
int size[200002];
int sum[200002];
int real[100002];
int cnt;
int find(int x)
{
	if(x==pre[x]) return x;
	else{
		pre[x]=find(pre[x]);
		return pre[x];
	}
}
int main(void)
{
	int n,m;
	int o,p,q;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		cnt=n;
		for(int i=1;i<=n;i++)
		{
		    pre[i]=i;
		    real[i]=i;
		    sum[i]=i;
		    size[i]=1;
		}
		for(int i=1;i<=m;i++)
		{    
		  scanf("%d",&o);
		  if(o==1){
			  scanf("%d%d",&p,&q);
			  int tx=find(real[p]),ty=find(real[q]);
	          if(tx!=ty)
	          {
		          pre[tx]=ty;
		          sum[ty]+=sum[tx];
		          size[ty]+=size[tx];
	          }
		  }
		  else if(o==2){
		  	  scanf("%d%d",&p,&q);
		  	  int tx=find(real[p]),ty=find(real[q]);
	          if(tx!=ty){
                    sum[tx]-=p;
	                size[tx]--;
                    real[p]=(++cnt);
                    pre[real[p]]=ty;
	                sum[ty]+=p;
	                size[ty]++;
              }
          }
		  else{
		  	scanf("%d",&p);
		  	int fp=find(real[p]);
		  	printf("%d %d\n",size[fp],sum[fp]);
		  }	  
		}
   }
} 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值