首页 > 代码库 > poj-1988-Cube Stacking
poj-1988-Cube Stacking
题目大意:有n个独立的磁铁(1-n标号)放在桌上,一个人对这个n堆进行移动操作,然后另外一个人进行询问。
规则:M a b 编号为a的磁铁放在编号为b的磁铁的顶端’
:C a 询问在磁铁a下面的磁铁的数目!
分析:利用并查集,每一堆磁铁看作一个集合,“M a b”就是将a归并到b的上面,每个集合都是有序的,设定三个变量
f:根节点,初始化时为本身;
all:以该节点为根的集合的元素个数;
num:该点到其根节点的距离(之间的元素个数);
那么all[f[a]]-num[a]-1就是以a节点为根节点的集合所含有的元素个数! (即磁铁个数!!!)
代码如下:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=52014; int n,num[maxn],all[maxn],f[maxn]; void init() { for(int i=1; i<maxn; i++) { f[i]=i; all[i]=1;//此时只有根节点自己一个! num[i]=0; } } int find(int x) { if(f[x]!=x) { int te=f[x]; f[x]=find(f[x]); num[x]+=num[te]; } return f[x]; } void unity(int a,int b) { int x=find(a),y=find(b); f[y]=x;//a的根节点是b的根节点的父节点!!! num[y]=all[x];//更新b的根节点到a的根节点的距离! all[x]+=all[y];//因为有新的磁铁集合a放到了b上面,所以更新all[a]! } int main() { int t; while(cin>>t) { n=t; init(); while(t--) { char str[12]; int a,b; cin>>str; if(str[0]=='M') { //把a放在b的上面! cin>>a>>b; unity(a,b); } else { cin>>a;//是压在a下面的磁铁! cout<<all[find(a)]-num[a]-1<<endl;//除去a这个磁铁以外! } } } return 0; }
poj-1988-Cube Stacking
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。