首页 > 其他 > 详细

hdu2818 Building Block

时间:2014-03-12 00:16:55      阅读:431      评论:0      收藏:0      [点我收藏+]

简单的种类并查集

每次用并查集模板合并时 因为小的合并到大的上面可以减小树的高度 所以每次都是判断大小再合并的

但是这种题目 为啥这样就错列?只能从一堆合并到另一堆

此题中,vis[a]存a为根的集合元素个数,num[a]存a所在的集合元素个数

merge和root的过程和树的形状、包括递归顺序无关的吧?



#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#define inf 0x3f3f3f3f
#define ll __int64
using namespace std;

int r[30005],vis[30005],num[30005];

int root(int a)
{
    if(r[a]==a) return a;
    int tmp=r[a];
    r[a]=root(r[a]);
    num[a]+=num[tmp];//从根结点一层层递加
    return r[a];
}

void merge(int a,int b)
{
    int ra,rb;
    ra=root(a);
    rb=root(b);
    if(ra==rb) return ;
    r[ra]=rb;
    num[ra]=vis[rb];//给a根结点赋初值(之前肯定是0)
    vis[rb]+=vis[ra];

}

int main()
{
    int p,i,a,b;
    char s[5];
    while(~scanf("%d",&p))
    {
        for(i=0;i<=30000;i++)
            vis[i]=1,r[i]=i;
        memset(num,0,sizeof num);
        while(p--)
        {
            scanf("%s",s);
            if(s[0]==‘M‘)
            {
                scanf("%d%d",&a,&b);
                merge(a,b);
                continue;
            }
            else
            {
                scanf("%d",&a);
                root(a);
                printf("%d\n",num[a]);
            }
        }
    }
    return 0;
}


hdu2818 Building Block,布布扣,bubuko.com

hdu2818 Building Block

原文:http://blog.csdn.net/u011032846/article/details/21042363

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!