您的位置:首页 > 产品设计 > UI/UE

HDU【2812】Building Block

2016-01-23 11:26 531 查看

Building Block

[b]Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4269 Accepted Submission(s): 1334

[/b]

[align=left]Problem Description[/align]
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.

[align=left]Input[/align]
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.

[align=left]Output[/align]
Output the count for each C operations in one line.

[align=left]Sample Input[/align]

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


[align=left]Sample Output[/align]

1
0
2


#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn = 30005;
int fa[maxn];//父亲结点
int low[maxn];//该点以下的砖块
int high[maxn];//包含该砖块的并查集中包括的砖块总和

void init()
{
for(int i = 0 ; i < maxn; i++)
{
fa[i] = i;
low[i] = 0;
high[i] = 1;
}
}

int Find(int x)
{
if(x != fa[x])
{
int root = Find(fa[x]);         //递归的时候更新low数组,需要细细体会。
low[x] += low[fa[x]];
return fa[x] = root;
}
else
return  x;
}

int main()
{
int P,x,y;
char c;
scanf("%d%*c",&P);
init();
while(P--)
{
scanf("%c",&c);
if(c == 'M')
{
scanf("%d%d%*c",&x,&y);                    //后面的%*c是为了消除换行符
int fx = Find(x),fy = Find(y);
if(fx == fy) continue;
fa[fx] = fy;
low[fx] = high[fy];
high[fy] += high[fx];
}
else if(c == 'C')
{
scanf("%d%*c",&x);
Find(x);
cout << low[x] << endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: