POJ 1988-Cube Stacking

来源:互联网 发布:网络直播推广软文 编辑:程序博客网 时间:2024/06/06 06:30

点击链接打开题目


题目大意:N个方块、P个操作。操作分为两种:(1):"M x y "表示将含有编号x的方块整体放在含有y的方块整体的上面;(2):“C x”表示询问在x下方有多少个方块?(N<=30000,P<=10^5)


解析:明显的并查集,在并查集的基本操作中加入两个数组,一个记录该子树中元素的个数,一个记录该盒子上面盒子的个数。


#include <iostream>#include <cstdio>using namespace std;const int Max=30005;int p;//有N个方块//fa[n]表示方块n的父亲结点//ro[n]表示方块n与根节点的距离//ma[n]表示方块n所在树的方块的个数int fa[Max],ro[Max],ma[Max];//初始化每个位置的方块及其编号void init(){for(int i=0;i<Max;i++){fa[i]=i;//初始每个方块的父亲节点都是自己ro[i]=0;ma[i]=1;}}//查找并查集x的祖先int find(int x){int fax=fa[x];//x的父亲结点//x不是自己所在树的根结点,则递归搜索if(ro[x]!=0){fax=find(fa[x]);ro[x]+=ro[fa[x]];}return fa[x]=fax;}//将两个集合合并void U(int x,int y){int fax=find(x),fay=find(y);fa[fay]=fax;//fay所在的树合并到fax所在的树的下面ro[fay]+=ma[fax];ma[fax]+=ma[fay];}int main(){char op;//表示操作的种类int a,b;while(scanf("%d",&p)!=-1){//初始化init();while(p--){cin>>op;if(op=='C'){cin>>a;//输出a下方盒子的个数cout<<ma[find(a)]-ro[a]-1<<endl;}else{cin>>a>>b;U(a,b);}}}return 0;}


原创粉丝点击