poj1988 Cube Stacking(并查集

题目地址:http://poj.org/problem?id=1988

 

题意:共n个数,p个操作。输入p。有两个操作M和C。M x y表示把x所在的栈放到y所在的栈上(比如M 2 6:[2 4]放到[1 6]上为[2 4 1 6]),C x为输出x下面有几个数。

 

思路:并查集每个集合以栈最下面的数为根,维护两个数组num[x]表示x所在集合节点总数,count[x]表示x下方节点个数。每次查找压缩路径的时候更新count(换父节点的时候每轮都把父节点的count加给儿子,就可以一直更新到x所在栈的最底下),合并的时候更新px的count和py的num(把x的栈放到y的栈上,x下面多了num[y]个节点,新栈总根y总数增加num[x]个)。【不管是M还是C,先found一下x,把x的fa[x]更新到栈的最底下,count[x]才是真正的数!】

 

 1 #include <iostream>
 2 #include <cstdio>
 3 
 4 using namespace std;
 5 
 6 const int maxn = 30000 + 5;
 7 struct c
 8 {
 9     int fa, count, num;
10 }cube[maxn];
11 
12 void init(int n)
13 {
14     for(int i = 1; i <= n; i++)
15     {
16         cube[i].fa = i;
17         cube[i].num = 1;
18         cube[i].count = 0;
19     }
20 }
21 
22 int found(int x)
23 {
24     if(cube[x].fa == x)
25         return x;
26     int px = cube[x].fa;
27     cube[x].fa = found(cube[x].fa);
28     cube[x].count += cube[px].count;
29     return cube[x].fa;
30 }
31 
32 void unite(int x, int y)
33 {
34     int px = cube[x].fa;
35     int py = cube[y].fa;
36     if(px != py)
37     {
38         cube[px].fa = py;
39         cube[px].count += cube[py].num;
40         cube[py].num += cube[px].num;
41     }
42 }
43 
44 int main()
45 {
46     int p, x, y;
47     char opr;
48     init(maxn);
49     scanf("%d", &p);
50     while(p--)
51     {
52         getchar();
53         scanf("%c", &opr);
54         if(opr == 'M')
55         {
56             scanf("%d%d", &x, &y);
57             int px = found(x);
58             int py = found(y);
59             if(px != py)
60                 unite(x, y);
61         }
62         else
63         {
64             scanf("%d", &x);
65             found(x);
66             printf("%d\n", cube[x].count);
67         }
68     }
69     return 0;
70 }
View Code

 

posted @ 2015-08-20 23:28  _正版索粒  阅读(128)  评论(0编辑  收藏  举报