hdu-2818/POJ-1988 Building Block(并查集+路径压缩)

来源:互联网 发布:基调网络监测 编辑:程序博客网 时间:2024/06/05 14:58

Building Block

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4430    Accepted Submission(s): 1373


Problem Description
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.
 

Input
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.
 

Output
Output the count for each C operations in one line.
 

Sample Input
6M 1 6C 1M 2 4M 2 6C 3C 4
 

Sample Output
10

2

题意+思路参考别人:进行m次操作,M x y 将包含x的集合移动到y上面,C x, 计算x下面有几个元素。用p[x]表示x的根结点,

cnt[x]表示x所在集合的元素个数,top[x]表示x上面有几个元素。每次进行路径压缩时,top[x]都要加上

top[p[x]],cnt和p的操作就是并查集的基本操作。最后计算结果是用x所在集合元素的个数 - 在它之上

的个数 - 它本身。

代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 30010int pre[N];int s[N];int top[N];int finds(int x){    int t;    if(x!=pre[x])    {        t=pre[x];        pre[x]=finds(pre[x]);        top[x]+=top[t];    }    return pre[x];}void mix(int a,int b){    int x=finds(a),y=finds(b);    if(x!=y)    {        pre[y]=x;        top[y]=s[x];        s[x]+=s[y];    }}int main(){    int T;    scanf("%d",&T);        char op[2];        int x,y;        for(int i=1;i<=N;i++)            {                pre[i]=i;                top[i]=0;                s[i]=1;            }        while(T--)        {            scanf("%s",op);            if(op[0]=='M')            {                scanf("%d %d",&x,&y);                mix(x,y);            }            else            {                scanf("%d",&x);                int nx=finds(x);                printf("%d\n",s[nx]-top[x]-1);            }        }    return 0;}

0 0
原创粉丝点击