【UVA 11987】并查集

来源:互联网 发布:json 查找 编辑:程序博客网 时间:2024/06/04 01:27

题目链接:

UVA-11987

题解:

就是简单的并查集,只不过包括了转移一个元素,而不是整个集合。方法很简单:
法一:
将对每一个元素,将他们的祖先设置成一个不存在的结点,这样就可以自由的操作了,并对每个集合直接进行修改。
法二:
(某whx同学教我的)无需删除被移除的元素,只要将它标记一下,再在将要被移到的那个集合里加上那个元素即可。

下面我给出法一的代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 400010int f[N],size[N];long long sum[N];int n,m,opt;int find(int x) { return x == f[x] ? x : f[x] = find(f[x]); }int main(){    int p,q;    while(scanf("%d%d",&n,&m) != EOF)    {    for(int i = 1;i <= n;i++) {f[i] = i+n;f[i+n] = i+n;size[i+n] = 1; sum[i+n] = i; }    while(m--)    {        scanf("%d",&opt);        if(opt == 1)        {            scanf("%d%d",&p,&q);            int fa = find(p),fb = find(q);            if(fa != fb)            {                f[fb] = fa;                size[fa] += size[fb];                sum[fa] += sum[fb];            }        }        if(opt == 2)        {            scanf("%d%d",&p,&q);            int fa = find(p),fb = find(q);            if(fa != fb)            {                f[p] = fb;                size[fb] ++; sum[fb] += p;                size[fa] --; sum[fa] -= p;            }        }        if(opt == 3)        {            scanf("%d",&p);            int fa = find(p);            printf("%d %lld\n",size[fa],sum[fa]);        }    }    }    return 0;}
1 0
原创粉丝点击