POJ 1988【并查集+记录个数】

题目:Cube Stacking

题意:

有N个cube,编号1-N,有两种操作:

操作1: M x y 把含有cube的堆堆放在含有y的堆的上面。

操作2: C x 询问cube编号为x的下面有多少个cube。

解题思路:

黑书上有类似题目,属于带有查询操作的并查集。设置两个变量D, C,D[i]表示i下面有几个cube, C[i],表示以i根时儿子个数,也就是堆在它上面的cube总个数。在每个M,C操作都要对x,y结点进行更新,有两种更新,一个是更新D[i],不停向根累加,一个是路径压缩。具体参考代码。 

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <algorithm>
6 #include <vector>
7 #include <map>
8
9 using namespace std;
10
11 const int MAX = 30000 + 10;
12 int Root[MAX];
13 int D[MAX], C[MAX];
14 int P;
15 char OP[10];
16
17 void init()
18 {
19 for(int i = 1; i < MAX; ++i)
20 {
21 Root[i] = i;
22 D[i] = 0;
23 C[i] = 1;
24 }
25 }
26 int update(int x)
27 {
28 if(Root[x] == x)
29 return 0;
30 else
31 return D[x] += update(Root[x]);
32 }
33
34 int findRoot(int x)
35 {
36 return Root[x] == x ? x : Root[x] = findRoot(Root[x]);
37 }
38 int main()
39 {
40 freopen("in.txt","r",stdin);
41 int x, y;
42 init();
43 scanf("%d", &P);
44 while(P--)
45 {
46 scanf("%s", OP);
47 if(strcmp(OP, "M") == 0)
48 {
49 scanf("%d%d", &x, &y);
50 update(x);
51 int nx = findRoot(x);
52 update(y);
53 int ny = findRoot(y);
54 Root[nx] = ny;
55 D[nx] = C[ny];
56 C[ny] += C[nx];
57 }
58 else if(strcmp(OP, "C") == 0)
59 {
60 scanf("%d", &x);
61 update(x);
62 findRoot(x);
63 printf("%d\n", D[x]);
64 }
65 }
66 return 0;
67 }



posted on 2011-09-24 20:36  Kenfly  阅读(274)  评论(0编辑  收藏  举报