Cube Stacking POJ - 1988 并查集

来源:互联网 发布:sql server个人版安装 编辑:程序博客网 时间:2024/05/16 14:55

Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations:
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.

Write a program that can verify the results of the game.
Input
* Line 1: A single integer, P

  • Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a ‘M’ for a move operation or a ‘C’ for a count operation. For move operations, the line also contains two integers: X and Y.For count operations, the line also contains a single integer: X.

Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
Output
Print the output from each of the count operations in the same order as the input file.
Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
1
0
2

本文参照博客http://blog.csdn.net/ascii991/article/details/7536826所写
看了他的博客后我发现代码在oj上通过不了,做了点小小的修改,并在我理解困难的地方加了解释

fa[]父节点位置,d[x]是x距离根节点的垂直距离,s[x]是x所在树的节点数量

#include <iostream>#include<cstdio>using namespace std;const int maxn = 30007;int fa[maxn], d[maxn], s[maxn];int p;int find(int x){    if (fa[x] == x) return x;    int t = fa[x];    fa[x] = find(fa[x]);    d[x] += d[t];     /*递归,每次对d[x]加的方向为 根->x节点。     在这里d[x]是x到其父亲节点的距离,而非其到根节点的距离。比如,如下图。     求d[14],find(14)的过程为:d[11]+=d[5].d[14]+=d[11].     同时压缩路径,14直接连到5下面。*/    return fa[x];}void unite(int x, int y){    x = find(x);    y = find(y);    fa[x] = y;    d[x] += s[y];    s[y] += s[x];}int main(){    int i, x, y;    char ch;    for (i = 1; i <= maxn; i++)    {        s[i] = 1; d[i] = 0;fa[i] = i;    }    scanf("%d", &p);    for (i = 1; i <= p; i++)    {        getchar();   //这个就是防止回车作为字符被输入ch        scanf("%c", &ch);        if (ch=='M')        {            scanf("%d%d", &x, &y);            unite(x, y);        }        else{                       scanf("%d", &x);            find(x);    /*这里要有个find(x)在合并之后,肯能出现下面的情况,    此时求14到跟的距离,若没有find(x),求出的是3,即14到其父亲节点的距离,    而通过find(x),将路径压缩,    同时从上而下将每个节点距离其父节点的距离相加,得到结果。*/            pintf("%d\n", d[x]);        }    }    return 0;}

举例

0 0
原创粉丝点击