• 注册
当前位置:1313e > 默认分类 >正文

poj1988 简单并查集

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 
#include 
#include 
#include 
#include 
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]);}}
}

 

转载于:https://www.cnblogs.com/xuejianye/p/5699472.html

本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 162202241@qq.com 举报,一经查实,本站将立刻删除。

最新评论

欢迎您发表评论:

请登录之后再进行评论

登录