#include
using namespace std;
const int MAXLEN = 30001;
/*
**num[i]-->i为树根的结点个数
**rank[i]-->i砖块下的结点数
**
*/
int id[MAXLEN],num[MAXLEN],rank[MAXLEN];
/**************************************************
*@func 寻找x的根节点,同时更新x下面的砖块数
*
*************************************************/
int find_op(int x){
if(x==id[x]) return id[x];
int fa = id[x];
id[x] = find_op(fa);
if(rank[fa] != 0)
rank[x] += rank[fa];
return id[x];
}
/*******************************************************
* |-----| |-----| |-----| leaf
* | x | + | y | ===> | x | |
* |-----| |-----| |-----| |
* | y | |
* |-----| root
*在做union操作的时候,把X所在的树的根接到y的树根上,
*1. x的树根下有y所在的树的结点总和。
*2. x所在的树并入y所在的树,x树消失,num[x_root] = 0
*3. y所在的树结点树增多,增加的数量为x树的结点数
*4. 注意这里只把x的树根接入y的树根,x的子节点都还保持原来的
* 父节点,将在 find操作的时候更新
*
*******************************************************/
void union_op(int x, int y){
int x_root = find_op(x);
int y_root = find_op(y);
if(x_root == y_root) return;
id[x_root] =y_root;
rank[x_root] = num[y_root];
num[y_root] += num[x_root];
num[x_root] = 0;
}
int main(){
for(int i=0; i
>pnum;
char p;
int x,y;
for(int i=0;i
>p;
if(p=='M'){
cin>>x>>y;
union_op(x,y);
}else{
cin>>x;
find_op(x);
cout<
<
注释图片在CODE格式化的时候排版出现了问题。
关于带权并查集可以参考下面两篇博文。