Description
John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:
M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
C X : Count the number of blocks under block X
You are request to find out the output for each C operation.
M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
C X : Count the number of blocks under block X
You are request to find out the output for each C operation.
Input
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.
Output
Output the count for each C operations in one line.
Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
1
0
2
今天打比赛前写的一道带权并查集
题意 搬砖头 把包含有 a的砖头堆里的 所有砖头 转移到 包含b的砖头堆上 问 K砖头下有几块砖头
思路 :并查集 额外开两个数组 一个记录这堆砖头堆的砖头高度 另一个记录k砖头下有几块砖头 每次合并的时候更新砖头高度 和被合并的砖头堆 最底下砖头 下面有几块砖头 用户find 时更新
ac code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <algorithm>
#include <cstdlib>
using namespace std;
const int maxn=30005;
int root[maxn],under[maxn],height[maxn];
void init(int n)
{
for(int i=0;i<=n;i++)
root[i]=i,under[i]=0,height[i]=1;
}
int fin(int x)
{
if(root[x]==x) return x;
int rot=root[x];
root[x]=fin(root[x]);
under[x]+=under[rot];//递归更新要查找的点
return root[x];
}
void Union(int u,int v)
{
int ru=fin(u);
int rv=fin(v);
if(ru==rv) return;
root[ru]=rv;//ru堆的最底下变成了rv
under[ru]=height[rv];//ru砖头下有rv块砖头
height[rv]+=height[ru];//更新rv堆砖头高度
}
int main()
{
char ch[5];
int u,v,n;
while(scanf("%d",&n)!=EOF)
{
init(n<30000?n:30000);
for(int i=0;i<n;i++)
{
scanf("%s",ch);
if(ch[0]=='M')
{
scanf("%d%d",&u,&v);
Union(u,v);
}
else
{
scanf("%d",&u);
fin(u);//这里必须有 因为算法是延迟更新的 这里如果不查找 就不会更新
printf("%d\n",under[u]);
}
}
}
return 0;
}
现在也找不到什么带权并查集的题了 也就发了两篇博客 总的来说 带权并查集的核心在于 延迟更新
建图的时候理清楚合并的集合的关系就好办了