UVA - 11987 Almost Union-Find (带删除的并查集)

题目链接

题目大意:

     题目中给出几个操作,1:把p、q两个集合合并;2:把p移到集合q里面;3:输出p所在集合的元素数量以及这些元素的和。

题目思路:

     两个集合合并我们知道,就是把p的根节点接在q的根节点上,而把p移到集合q里呢?仅仅令 f a [ p ] = q 的根节点就好了吗?

当然不行。这样做我们只是把p移到了集合q里,但是如果p不是叶子节点,那么p下面的儿子们也随之移到了集合q里。

     但是我们可以这样想,能不能把p点单独分离出来,让它单独成为一个集合,那么就相当于把{p}与集合q合并,不用担心下面孩子也会动的问题了;

     具体实现:开一个id[]数组用来保存p的信息即可。

     至于输出集合的元素及他们的和我们可以分别用num[]和sum[]来随时保存。(移动的时候做相应加减)

代码:

#include<iostream>
#include<cstdio>
#define maxn 300005

using namespace std;
int fa[maxn];
int num[maxn],sum[maxn];
int id[maxn];//怎么不把儿子们带过去呢……
int n,m;

int finds(int x)
{
     return fa[x]==x?x:finds(fa[x]);
}
void remove1(int a,int b)//连根一起移过去
{
     a=finds(a);
     b=finds(b);
     if(a!=b)
     {
          fa[a]=b;
          num[b]+=num[a];
          num[a]=0;//以aa为根节点的集合中元素数为0
          sum[b]+=sum[a];
          sum[a]=0;
     }

}
void remove2(int a,int b)//只移动a
{
     int aa=finds(id[a]);
     int bb=finds(b);
     if(aa!=bb)
     {
          id[a]=++n;
          fa[n]=bb;
          num[bb]++;
          num[aa]--;
          sum[bb]+=a;
          sum[aa]-=a;
     }
}
int main(void)
{

     int d,p,q;
     int pp,qq;
     while(~scanf("%d%d",&n,&m))
     {
          for(int i=1;i<=n;i++)
          {
               id[i]=i;
               num[i]=1;
               sum[i]=i;
               fa[i]=i;
          }
          for(int i=0;i<m;i++)
          {
               scanf("%d",&d);
               switch(d)
               {
                    case 1:
                         scanf("%d%d",&p,&q);
                         remove1(id[p],id[q]);
                         break;
                    case 2:
                         scanf("%d%d",&p,&q);
                         remove2(p,id[q]);//后面还需要p
                         break;
                    case 3:
                         scanf("%d",&p);
                         pp=finds(id[p]);
                         printf("%d %d\n",num[pp],sum[pp]);//以根节点为代表
                         break;
               }
          }
     }
     return 0;
}

呼呼

猜你喜欢

转载自blog.csdn.net/destiny1507/article/details/81461659