HDU2818 并查集
Building Block
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5341 Accepted Submission(s): 1638
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
Source
题意:
p次操作,M x y 表示将x所在的一堆所有数放到y所在的一堆上面,C x 表示询问数字x下方有几个数字。
代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int fat[30004],num[30004],sum[30004];//num[i]记录数i下面有几个数,sum[i]记录以i为根节点的并查集有几个元素 5 void init() 6 { 7 for(int i=0;i<=30001;i++){ 8 fat[i]=i; 9 num[i]=0; 10 sum[i]=1; 11 } 12 } 13 int find(int x) 14 { 15 if(fat[x]!=x){ 16 int tem=fat[x]; 17 fat[x]=find(tem); 18 num[x]+=num[tem]; 19 } 20 return fat[x]; 21 } 22 void connect(int x,int y) 23 { 24 int a=find(x),b=find(y); 25 if(a!=b){ 26 fat[a]=b; 27 num[a]=sum[b]; 28 sum[b]+=sum[a]; 29 } 30 } 31 int main() 32 { 33 int p,x,y; 34 char ch; 35 while(scanf("%d",&p)!=EOF){ 36 init(); 37 while(p--){ 38 cin>>ch; 39 if(ch=='M'){ 40 scanf("%d%d",&x,&y); 41 connect(x,y); 42 } 43 else{ 44 scanf("%d",&x); 45 find(x); //更新一下num 46 printf("%d\n",num[x]); 47 } 48 } 49 } 50 return 0; 51 }