并查集——nkoj2281方块游戏

来源:互联网 发布:网络教育考试可以抄吗 编辑:程序博客网 时间:2024/06/08 15:09

方块游戏

Description

FJ 和贝茜 用 N (1 <= N <= 30,000)块相同的小立方块玩游戏,小方块编号为 1..N。开始时,小方块都单独分开的, 每个看成一个柱子, 即有 N 柱子。 FJ 要 贝茜做 P(1 <= P <= 100,000) 个操作,操作有两种类型: 
(1) FJ 要求贝茜把X 号方块所在的柱子放到 Y号所在的柱子上面,成一个新柱子。 
(2)FJ 要求贝茜计算 X 号方块所在柱子,它下面有多少个小方块。 
请编个程序,帮助贝茜计算。 

Input

*第一行:一个整数 P 
*第 2..P+1行:第 i+1行表示第 i个FJ要求的合法操作。如果这行以'M'开头,后面有两个整数 X,y 表示要进入(1)操作。 
如果这行以'C'开头,后面有一个整数 X,表示要求计算 X所在柱子下面的方块个数。 

注:所有操作都是合法的。N 并没有出现在输入文件中。 

Output

依次要求计算的值,每次一行。 

Sample Input

6  M 1 6 C 1 M 2 4 M 2 6 C 3 C 4 

Sample Output

1 0 2 

Hint

样例说明: 
6 : 6 个操作 
M 1 6 : 1,6 / 2 / 3 / 4 / 5 把 1放在 6 上面。 
C 1 : 输出:1 
M 2 4 : 1,6 / 2,4 / 3 / 5 
M 2 6 : 2,4,1,6 / 3 / 5 
C 3 : 输出 :0 
C 4 : 输出: 2 

#include<cstdio>#include<iostream>using namespace std;int count[50005],before[50005],father[50005];//count[x]记录以x为开头的柱子长度,before[x]是x所在柱子x上面的方块个数 int getfather(int x)//找爸爸,同时更新before和count {int dad;if(father[x]==x)return x;dad=getfather(father[x]);before[x]=before[x]+before[father[x]];//这句必须放在上一句后面 father[x]=dad;return father[x];}void merge(int x,int y)//把x柱子放到y柱子上面 {x=getfather(x);y=getfather(y);father[y]=x;before[y]=before[y]+count[x];count[x]=count[x]+count[y];}int main(){int p,x,y,t,i,j,k;char ch;cin>>p;for(i=1;i<=30005;i++){father[i]=i;count[i]=1;}for(i=1;i<=p;i++){for(ch=getchar();ch!='M'&&ch!='C';)ch=getchar();if(ch=='M'){scanf("%d%d",&x,&y);merge(x,y);}else{scanf("%d",&x);y=getfather(x);printf("%d\n",count[y]-before[x]-1);}}}


0 0
原创粉丝点击