• UVA11987Almost UnionFind并查集的基本操作合并、删除、移位


    I hope you know the beautiful Union-Find structure. In this problem, you’re to implement something similar, but not identical. The data structure you need to write is also a collection of disjoint sets, supporting 3 operations:

    Initially, the collection contains n sets: {1}, {2}, {3}, . . . , {n}.

    题意:

    涉及到并查集的删除操作
    1 合并这两个集合
    2 将p移到q集合中去
    3 统计元素个数和全部元素的和 相当于询问输出结果

    5 7 ->5个集合,7种操作
    1 1 2
    2 3 4
    1 3 5
    3 4 ->3 12
    2 4 1
    3 4 ->3 7
    3 3 ->2 8

    #include<iostream>
    #include<stdio.h>
    using namespace std;
    typedef long long ll;
    
    const int N=1e5+10;
    int f[N*2],ii[N*2],num[N*2];
    ll sum[N*2];
    int n,m,cnt;
    
    void init()
    {
        for(int i=1;i<=n;i++)
        {
            f[i]=i;
            ii[i]=i;
            sum[i]=i;
            num[i]=1;
        }
        cnt=n;
    }
    
    int getf(int x)
    {
        if(f[x]==x)
            return x;
        return f[x]=getf(f[x]);
    }
    
    void merge(int x,int y)
    {
        int t1=getf(ii[x]);
        int t2=getf(ii[y]);
        if(t1!=t2)
            f[t2]=t1;
        num[t1]+=num[t2];
        sum[t1]+=sum[t2];
    }
    
    void deletee(int x)
    {
        int p=ii[x];
        sum[getf(p)]-=x;
        num[getf(p)]--;
        ii[x]=++cnt;
        sum[ii[x]]=x;
        num[ii[x]]=1;
        f[ii[x]]=ii[x];
    }
    
    
    int main()
    {
        int op,p,q;
        while(~scanf("%d %d",&n,&m))
        {
            init();
            for(int i=1;i<=m;i++)
            {
                scanf("%d",&op);
                if(op==1)//合并这两个集合
                {
                    scanf("%d %d",&p,&q);
                    if(getf(ii[p])==getf(ii[q]))
                        continue;
                    else
                        merge(p,q);
                }
                else if(op==2)//将p移到q集合中去
                {
                    scanf("%d %d",&p,&q);
                    if(getf(ii[p])!=getf(ii[q]))//如果不在同一个集合中
                    {
                        deletee(p);
                        merge(p,q);
                    }
                }
                else if(op==3)//统计元素个数和全部元素的和 相当于询问输出结果
                {
                    scanf("%d",&p);
                    int k=getf(ii[p]);
                    printf("%d %lld\n",num[k],sum[k]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    03-hibernate注解-关系映射级别注解-一对一
    02-hibernate注解-属性级别注解
    linux下使用vim替换文件中的^M换行符
    maven项目中找不到Maven Dependencies解决办法
    软件设计师教程(第5版)- 前言和目录
    wireshark抓包分析工具的使用
    Tcpdump抓包工具的使用
    如何使用maven优雅地管理项目版本号
    Linux系统盘扩容-物理机非虚拟机
    eclipse下安装windowbuilder(一定要看)
  • 原文地址:https://www.cnblogs.com/OFSHK/p/11380869.html
Copyright © 2020-2023  润新知