码迷,mamicode.com
首页 > 其他好文 > 详细

poj1988 简单并查集

时间:2016-07-23 21:07:15      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:

B - 叠叠乐

Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:30000KB     64bit IO Format:%lld & %llu

Submit Status

Description

 

Input

 

Output

 

Sample Input

 

Sample Output

 

Hint

 

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
解析见代码:
/*
poj1988 ,并查集
题目大意:初始时有N块木块,编号1-N,分开放置,
然后对这些木块开始执行P条操作,M a,b是将a所在的
木块堆移到b所在的木块堆上,C a是查询编号为a的木块在
其之下有多少个木块
思路分析:如果查询的是a号木块所在的木块堆一共有多
少堆,那么这道题就是简单的维护下集合内元素数量就可以,但是现在
问的是它下面有多少块,所以还需要维护的就是它下面的木块数目
初始化under[i]=0,然后对于under数组的更新有两个地方,对于
一个子集的根节点(最下面的木块)在merge时就可以更新了,其他
的木块则是要在压缩路径的时候进行更新,under[i]=under[father[i]]
注意一定要先更新后 压缩路径,要不然就没有更新的效果
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
const int maxn=30000+100;
int father[maxn];
int sum[maxn];
int under[maxn];
int findroot(int x)
{
    if(x==father[x]) return x;
    int t=findroot(father[x]);
    under[x]+=under[father[x]];//先更新under数组,后压缩路径
    father[x]=t;
    return father[x];
}
void merge(int a,int b)//根是在下面的木块
{
    int pa=findroot(a);
    int pb=findroot(b);
    if(pa==pb) return;
    father[pb]=pa;
    under[pb]=sum[pa];
    sum[pa]+=sum[pb];
}
int main()
{
    for(int i=1;i<=maxn;i++)
    {
        father[i]=i;
        sum[i]=1;
        under[i]=0;
    }
    int p;
    scanf("%d",&p);
    char s[10];
    int a,b;
    while(p--)
    {
        scanf("%s",s);
        if(s[0]==M)
        {
            scanf("%d%d",&a,&b);
            merge(b,a);
        }
        else
        {
           scanf("%d",&a);
           findroot(a);//祖先节点可能发生了 变化 ,因此需要进行更新
           printf("%d\n",under[a]);
        }
    }
}

 

poj1988 简单并查集

标签:

原文地址:http://www.cnblogs.com/xuejianye/p/5699472.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!