码迷,mamicode.com
首页 > 其他好文 > 详细

UVA11987Almost Union-Find(并查集删除节点)

时间:2016-03-07 01:17:46      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

题目链接

题意:n个数(即1-n)和m个操作:

1表示把x和y合并,2表示把x移到y集合里面,3表示统计x集合的元素个数

1,3好说,关键是2操作,可以先把2删除掉,删除的操作可以找一个其他的数字来取代x,这样就有新生出来一个集合,移到y集合就合并

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100000;
typedef long long LL;
int father[N + N + 10];
int sum[N + N + 10],cnt[N + N + 10];  // sum求集合里面所有元素和,cnt表示个数
int value[N + N + 10]; //表示第i个数值 
int n,m,k;
void init()
{
    k = n + 1;
    for(int i = 0; i <= n; i++)
    {
        father[i] = i;
        sum[i] = i;
        cnt[i] = 1;
        value[i] = i;
    }
}
int Find(int x)
{
    if(x == father[x])
        return x;
    return father[x] = Find(father[x]);
}
void Union(int x, int y)
{
    int fx = Find(x);
    int fy = Find(y);
    if(fx != fy)
    {
        father[fx] = fy;
        sum[fy] += sum[fx];
        cnt[fy] += cnt[fx];
    }
}
void Remove(int x)
{
    /*
    int fx = Find(value[x]);
    cnt[fx]--;
    sum[fx] -= x;
    value[x] = k;
    int fy = Find(value[y]);
    father[k] = fy;
    cnt[fy]++;
    sum[fy] += x;
    k++;
    */
    int fx = Find(value[x]);
    cnt[fx]--;  // 删除x时从父节点集合中减一
    sum[fx] -= x;  // sum中减去x
    value[x] = k;  // 用 k 来代替 x ,生成了一个单独的集合,父节点是k
    cnt[k] = 1;    
    sum[k] = x;
    father[k] = k;
    k++;
}
int main()
{
    while(scanf("%d%d", &n, &m) != EOF)
    {
        k = n + 1;
        for(int i = 0; i <= n; i++)
        {
            father[i] = i;
            sum[i] = i;
            cnt[i] = 1;
            value[i] = i;
        }
        int order,p,q;
        while(m--)
        {
            scanf("%d", &order);
            if(order == 1)
            {
                scanf("%d%d", &p, &q);
                Union(value[p], value[q]);
            }
            else if(order == 2)
            {
                scanf("%d%d", &p, &q);
                int fx = Find(value[p]);
                int fy = Find(value[q]);
                if(fx != fy)   // 如果p和q本来就在一个集合,就不用操作了。但是少了这个就wa了,不明白为什么操作不行
                {
                    Remove(p);
                    Union(value[p], value[q]);
                }
            }
            else if(order == 3)
            {
                scanf("%d", &p);
                int fx = Find(value[p]);
                printf("%d %d\n", cnt[fx], sum[fx]);
            }
        }
    }
    return 0;
}

  

UVA11987Almost Union-Find(并查集删除节点)

标签:

原文地址:http://www.cnblogs.com/zhaopAC/p/5249060.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!