xtu 1464 堆叠积木

描述
约翰和贝西在玩叠积木的游戏。共有N(1 ≤ N ≤ 30000)块积木,分别编号为1到N。起初,他们把这些积木平放在地上,自然地分成N堆,每堆只有一块。 积木之间可以相互堆叠,最后会越叠越高。约翰让贝西执行P(1 ≤ P ≤ 100000)条命令,命令可以分为两种类型:
移动命令:贝西需要取出包含X的那堆积木,将它们完整地叠放到包含Y的那堆积木之上;
计数命令:贝西需要报告当前在编号为Z的积木之下压有多少块积木
请编写一个程序,帮助贝西输出正确的答案。

输入
第一行:单个整数:P
第二行到第P + 1行:每行描述了一条命令,保证所有的命令都是合法的。如果这行开头的字母是 M,代表一条移动命令,后面的两个整数代表上文中的X和Y;如果开头字母是 C,代表一条计数命令。后面的整数代表上文中的Z。

输出
对每一个计数命令,输出正确的数字,每个数字之间用换行符分开。

样例输入
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4

样例输出
1
0
2

提示
第一次回答时,1下面只有一个6;第二次回答时,下面没有任何积木;3第三次回答时,4下面有两块积木:1和6。

思路:

合并时找出集合节点,依次往下,到最后一个节点,最后将最后一个节点加上b[y]+1,并置y 为x的孩子,此时x为上一集合的最底层的一个元素。

代码:

 #include<stdio.h>
short a[30001],b[30001],c[30001],x,y,ma=30000;
int f(int i)
{
   if(a[i]==i) return i;
   return a[i]=f(a[i]);
}
void u(int i,int j)
{
    x=f(i),y=f(j);
   if(x==y) return;
   if(i>ma) ma=i;if(j>ma) ma=j;
   for(a[y]=x;c[x]!=-1;x=c[x]) b[x]+=1+b[y];
   b[x]+=1+b[y];c[x]=y;
}
int main()
{
  int n,i,j;char ch;
  while(scanf("%d",&n)!=EOF)
 {
    for(i=1;i<=ma;i++) a[i]=i,b[i]=0,c[i]=-1;
    while(n--)
  {
     ma=0;getchar();scanf("%c",&ch);
     if(ch=='M') scanf("%d%d",&i,&j),u(i,j);
     else scanf("%u",&i),printf("%d\n",b[i]);
   }
 }
 return 0;
}

转载于:https://www.cnblogs.com/jufu/archive/2011/10/19/2217231.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值