zoukankan      html  css  js  c++  java
  • Building Block

    Building Block

    Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 156 Accepted Submission(s): 70
     
    Problem Description
    John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation:

    M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command.
    C X : Count the number of blocks under block X

    You are request to find out the output for each C operation.
     
    Input
    The first line contains integer P. Then P lines follow, each of which contain an operation describe above.
     
    Output
    Output the count for each C operations in one line.
     
    Sample Input
    6
    M 1 6
    C 1
    M 2 4
    M 2 6
    C 3
    C 4
     
    Sample Output
    1
    0
    2
     
     
    Source
    2009 Multi-University Training Contest 1 - Host by TJU
     
    Recommend
    gaojie
     
    /*
    题意:两种操作:
            M X Y : 将x所在的木块堆上的所有木块转移到y所在的木块堆 
            C X : 查询x所在的木块堆x下方的木块的数量
            
    初步思路:很明显并查集
    
    #错误:T了一发,没有压缩路径,wa了一发,压缩路径写惨了
    */
    #include<bits/stdc++.h>
    using namespace std;
    int bin[300010];
    int under[300010];//表示以i为根节点的数有多少木块(也就是i节点一下有多少木块)
    int Rank[300010];//表示i节点所在的集合的木块数量
    int findx(int x){
        if(x!=bin[x]){
            int tmp=findx(bin[x]);
            under[x]+=under[bin[x]];
            bin[x]=tmp;
        }
        return bin[x];
    }
    void merge(int x,int y){
        int fx=findx(x);
        int fy=findx(y);
        if(fx!=fy){
            bin[fx]=fy;//将x放到y节点上面
            under[fx]+=Rank[fy];//x节点下面增加的肯定是y节点所在的全部木块
            Rank[fy]+=Rank[fx];
        }
    }
    int n;
    char op[2];
    int x,y;
    void init(){
        for(int i=0;i<300005;i++){
            bin[i]=i;
            Rank[i]=1;
            under[i]=0;
        }
    }
    int main(){
        //freopen("in.txt","r",stdin);
        while(scanf("%d",&n)!=EOF){    
            init();    
            while(n--){
                scanf("%s",op);
                if(op[0]=='M'){
                    scanf("%d%d",&x,&y);
                    merge(x,y);
                }else{//查找x这棵树有多少木块
                    scanf("%d",&x);
                    findx(x);
                    printf("%d
    ",under[x]);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    利用Python中SocketServer 实现客户端与服务器间非阻塞通信
    Redis单机配置多实例,实现主从同步
    Django(一) 安装使用基础
    数组模拟环形队列
    单链表原理及应用举例
    中缀表达式转换为后缀表达式(思路)
    中缀表达式转后缀表达式(代码实现)及前缀表达式思路补充
    数组模拟栈(Stack)
    双向链表原理及应用举例
    单向环形链表
  • 原文地址:https://www.cnblogs.com/wuwangchuxin0924/p/6390093.html
Copyright © 2011-2022 走看看