Building Block
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5939 Accepted Submission(s): 1842
Problem 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
题目说有N个板子,两个操作,M X Y表示把X板子所在的那一堆(X所在集合)放到Y板子所在的那一堆(Y所在集合);C X表示求X板子下边有几个板子;、
直接上代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#define MAX 30000+5
using namespace std;
int pre[MAX];//存父节点;
int d[MAX];//深度;
int r[MAX];//到根的距离;
int init(){ //初始化;
for(int i=0; i<=MAX; i++){//从0开始,数据的一个坑点;
pre[i]=i;
d[i]=0;
r[i]=1;
}
}
int Find(int x){
int fx;
if(x==pre[x]) return x;
fx=pre[x];
pre[x]=Find(fx);
d[x]=d[x]+d[fx];
return pre[x];
}
void Union(int x, int y){
int fx=Find(x), fy=Find(y);
if(fx==fy) return;
pre[fx]=fy; //把x放到y上,计算x下边的block数量,则以y为根节点,所求值则变为x到根节点的距离;
d[fx]=r[fy];
r[fy]+=r[fx];
return;
}
int main(){
int P;
scanf("%d",&P);
init();
while(P--){
char op[5];
int x, y;
scanf("%s",op);
if(op[0]=='M'){
scanf("%d%d",&x,&y);
Union(x,y);
}
else{
scanf("%d",&x);
Find(x);
printf("%d\n",d[x]);
}
}
return 0;
}