zoukankan      html  css  js  c++  java
  • POJ1988 Cube Stacking (带权并查集)

    Cube Stacking

    Time Limit: 2000MS   Memory Limit: 30000K
    Total Submissions: 31012   Accepted: 10904
    Case Time Limit: 1000MS

    Description

    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
    

    题目大意与分析

    本题在并查集的基础上,要求输出当前节点的子节点数量,其实可以转化为带权并查集的问题,求出当前节点的祖先的总子孙数量,减去当前节点到祖先的距离再减一即可

    带权并查集的介绍:https://blog.csdn.net/yjr3426619/article/details/82315133

    Up[x]代表x到自己的祖先的距离(也就是上面有多少节点)

    sums[x]代表以x为根节点的子孙数量(只对根节点有效,因为在合并时,非根节点的sums值将不再被更新)

    s[x]代表x的祖先

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <math.h>
    #include <cstdio>
    using namespace std;
    
    int s[30005],sums[30005],Up[30005],p;
    char C;
    
    int findf(int x){  
        if(s[x]==x)
        {
            return x;
        }
        else
        {
            int fx=s[x];
            s[x]=findf(s[x]);
            Up[x]+=Up[fx];          //修改x的Up值,因为x的父节点变化了,此时不需要修改sum值
            return s[x]; 
        }
    }
    
    void hebing (int x, int y){
        int fx=findf(x);
        int fy=findf(y);
        if(fx!=fy){
            s[fy]=fx;
            Up[fy]+=sums[fx];       //被合并时加上移过来的数量 
            sums[fx]+=sums[fy];     //只有在合并的时候才需要修改根节点的sum值 此时fy被合并 不作为根节点存在 
        }
    }
    
    int main(void)
    {
        cin>>p;
        for(int i=1;i<30005;i++)
        {
            sums[i]=1;
            Up[i]=0;
            s[i]=i;
        }
        while(p--)
        {
            cin>>C;
            if(C=='M')
            {
                int a,b;
                cin>>a>>b;
                hebing(a,b);
             } 
            else
            {
                int a;
                cin>>a;
                int fa=findf(a);
                cout<<sums[fa]-Up[a]-1<<endl;
            }
        }   
    }
  • 相关阅读:
    Navi.Soft31.WinForm框架(含下载地址)
    Navi.Soft31.阅读导航
    工作流组件示例(全部开源)
    WinForm中播放视频示例(含源码)
    angularjs实现选项卡实例
    angularjs中使用 <input type="file">标签实现一次最多上传5张图片
    angularjs笔记《二》
    input type="number"时,maxlength不起作用怎么解决
    笔记——《正则表达式》
    如何区分slice、splice和split
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/12551610.html
Copyright © 2011-2022 走看看