简单的种类并查集
每次用并查集模板合并时 因为小的合并到大的上面可以减小树的高度 所以每次都是判断大小再合并的
但是这种题目 为啥这样就错列?只能从一堆合并到另一堆
此题中,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
原文:http://blog.csdn.net/u011032846/article/details/21042363