http://acm.hdu.edu.cn/showproblem.php?pid=2818
有n条管pipe,能把砖块串起来,初始每条管穿了一个砖
题意: 有2种操作:
M x y把x的管放在y管的上面
C x求x的下面有多少个砖块
带权并查集,维护一个num[i]表示i到根节点之间有多少块砖,再维护一个tol[x]数组,表示管x上一共串有多少个砖块
合并就很简单了:
if (fx!=fy)
{
fa[fx]=fy;
num[fx]=tol[fy];<span style="white-space:pre"> </span>
tol[fy]+=tol[fx];
}
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int fa[31234];
int num[31234];
int tol[31234];
int find(int x)
{
if (fa[x]==x) return x;
int tmp=find(fa[x]);
num[x]=num[x]+num[fa[x]];
return fa[x]=tmp;
}
int main()
{
int n,m,k;
while(cin>>n)
{
int x,y,z;
char s[3];
for (int i=0; i<=31000; i++)fa[i]=i,num[i]=0,tol[i]=1;
for (int i=1; i<=n; i++)
{
scanf("%s",s);
if (s[0]=='M')
{
scanf("%d%d",&x,&y);
int fx=find(x);
int fy=find(y);
if (fx!=fy)
{
fa[fx]=fy;
num[fx]=tol[fy];
tol[fy]+=tol[fx];
}
}
else
{
scanf("%d",&x);
find(x);
printf("%d\n",num[x ]);
}
}
}
return 0;
}