zoukankan      html  css  js  c++  java
  • poj1988

    题意:有n个元素,开始每个元素自己一栈,有两种操作,将含有元素x的栈放在含有y的栈的顶端,合并为一个栈。第二种操作是询问含有x元素下面有多少个元素。

    分析:并查集,因为当我们知道栈中元素的总数,和某元素到栈顶的距离,我们就能知道这个元素下面有多少元素。我们并操作的时候,始终使用在上面栈的代表元来做合并之后的代表元,这样也就达到了栈中的代表元是栈中的堆顶元素的效果,我们只需在每个代表元中记录该栈中的元素总数即可。然而我们还需要得知某元素到代表元的距离,这样我们就需要记录每个元素到其父亲的距离,把它到代表元上所经过的距离加起来,即为它到代表元的距离。这样我们就得出了结果。另外优化的过程(把路上所有元素的father改为代表元的过程)比较复杂,容易错。

    View Code
    #include <iostream>
    #include
    <cstdlib>
    #include
    <cstring>
    #include
    <cstdio>
    usingnamespace std;

    #define maxn 30003

    struct Block
    {
    int father, tot, dis;
    }block[maxn];

    int n;

    void init()
    {
    for (int i =0; i < maxn; i++)
    {
    block[i].father
    = i;
    block[i].tot
    =1;
    block[i].dis
    =0;
    }
    }

    int getanc(int a)
    {
    int ret;
    if (block[a].father == a)
    return a;
    ret
    = getanc(block[a].father);
    block[a].dis
    += block[block[a].father].dis;
    block[a].father
    = ret;
    return ret;
    }

    void move()
    {
    int a, b;
    scanf(
    "%d%d", &a, &b);
    int anc1 = getanc(a);
    int anc2 = getanc(b);
    block[anc2].dis
    = block[anc1].tot;
    block[anc2].father
    = anc1;
    block[anc1].tot
    = block[anc1].tot + block[anc2].tot;
    }

    void count()
    {
    int a;
    scanf(
    "%d", &a);
    int anc = getanc(a);
    printf(
    "%d\n", block[anc].tot - block[a].dis -1);
    }

    int main()
    {
    //freopen("D:\\t.txt", "r", stdin);
    scanf("%d", &n);
    init();
    for (int i =0; i < n; i++)
    {
    char st[3];
    scanf(
    "%s", st);
    if (strcmp(st, "M") ==0)
    move();
    else
    count();
    }
    return0;
    }
  • 相关阅读:
    使用定时器实现获取手机验证码倒计时
    搜索历史管理
    利用vue和jQuery实现中国主要城市搜索与选择
    使用vue、jQuery生成带有logo的二维码
    使用vue-cli脚手架搭建Vue项目
    postcss-px-to-viewport
    git命令操作篇
    小程序中live-player
    对于常用数组的方法总结
    css的加载中动画
  • 原文地址:https://www.cnblogs.com/rainydays/p/1982677.html
Copyright © 2011-2022 走看看