POJ 1988 Cube Stacking(并查集)

来源:互联网 发布:知乎的缺点 编辑:程序博客网 时间:2024/05/16 17:57

题意:

有N堆方块(初始时每堆有一个方块),编号1~N,有两种操作:

M x y:将x所在堆的方块拿起来放到y所在堆的上边。

C x:标号为x的方块下面有多少个方块。

解题思路:暴力肯定会超时,这是一道并查集的题目。每一个方块有三个参数:

par:父亲结点的编号

under:当前结点下面的方块数目,在堆合并和路径压缩中都要更新

sum:如果该结点作为根结点,则表示的是该堆的方块总数

样例演示:


代码:

#include <cstdio>#include <cstring>#define M 50000int par[M], under[M], sum[M];int get_par(int u) {    if(par[u] != u) {        int tmp = par[u];        par[u] = get_par(par[u]);   //更改父亲结点        under[u] += under[tmp];     //更新under参数    }    return par[u];}int query(int a, int b) {    return get_par(a) == get_par(b);}void merge(int a, int b) {    int t1 = get_par(a);    int t2 = get_par(b);    under[t1] = sum[t2];    sum[t2] += sum[t1];    par[t1] = t2;}int main() {    int p;    char cmd[10];    int x, y;    while(~scanf("%d", &p)) {        for(int i=0; i<M; i++) par[i] = i;        memset(under, 0, sizeof(under));        for(int i=0; i<M; i++) sum[i] = 1;        for(int i=0; i<p; i++) {            scanf("%s", cmd);            switch(cmd[0]) {            case 'M':                scanf("%d%d", &x, &y);                merge(x, y);                break;            case 'C':                scanf("%d", &x);                get_par(x);                printf("%d\n", under[x]);                break;            }        }    }    return 0;}


0 0