F

- 题目大意

     初始有N个集合,分别为 1 ,2 ,3 .....n。一共有三种操件:
1、 p q 合并元素p和q的集合
2 、p q 把p元素移到q集合中
3 、p 输出p元素集合的个数及全部元素的和。

- 解题思路

    并查集操作。1、3步比较容易实现,只要建立一个sum[],cnt[],记录每个结点相应值,和并时把值更新到根结点,输出时只要找到根结点输出其值即可。第二步可以利用并查集的删除功能去构造即可。

- 代码

#include<cstdio>
using namespace std;
const int MAX=1e5+50;
int fa[MAX];
int num[MAX],id[MAX];
long long sum[MAX];
int find(int x)
{
    if(x==fa[x])
        return x;
    else
        return fa[x]=find(fa[x]);
}

void init(int n)
{
    for(int i=0;i<=n;i++)
       {
        sum[i]=fa[i]=id[i]=i;
        num[i]=1;
       }
}

void Union(int x,int y)
{
    int fx=find(x),fy=find(y);
    if(fx!=fy)
   {
    fa[fx]=fy;
    sum[fy]+=sum[fx];
    num[fy]+=num[fx];
   }
}
int main()
{
    int n,m,x,y,tmp;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        tmp=n;
        init(n);
        int choose;
        while(m--)
        {
        scanf("%d",&choose);
        if(choose==1)
        {
            scanf("%d%d",&x,&y);
            Union(id[x],id[y]);
        }
        else if(choose==2)
        {
            scanf("%d%d",&x,&y);
            int fx=find(id[x]),fy=find(id[y]);
            if(fx!=fy)
            {
                sum[fx]-=x;
                num[fx]--;
                tmp++;
                id[x]=tmp;
                fa[tmp]=tmp;
                num[tmp]=1;
                sum[tmp]=x;
                Union(id[x],id[y]);
            }
        }
        else
        {
            scanf("%d",&x);
            int fx=find(id[x]);
            printf("%d %d
",num[fx],sum[fx]);
        }
      }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/alpacadh/p/8449443.html