POJ 1988 Cube Stacking(带权的并查集)
2015-08-24 22:08
330 查看
题目链接:
http://poj.org/problem?id=1988
解题思路:
有很多个stack,一开始每个stack里面都有一个cube。
然后支持两种操作:
1.move x y: 将x所在的stack移动到y所在stack的顶部;
2.count x:查询在x所在stack中,在x之下的cube的个数。
算法思想:
带权的并查集。
设两个权值cnt[x],dis[x]分别代表以x为根结点的堆的碟子的个数和值为x的碟子到根结点的距离。
求x下面有多少碟子就等于cnt[pa[x]] - dis[x] - 1;
AC代码:
http://poj.org/problem?id=1988
解题思路:
有很多个stack,一开始每个stack里面都有一个cube。
然后支持两种操作:
1.move x y: 将x所在的stack移动到y所在stack的顶部;
2.count x:查询在x所在stack中,在x之下的cube的个数。
算法思想:
带权的并查集。
设两个权值cnt[x],dis[x]分别代表以x为根结点的堆的碟子的个数和值为x的碟子到根结点的距离。
求x下面有多少碟子就等于cnt[pa[x]] - dis[x] - 1;
AC代码:
#include <iostream> #include <cstdio> using namespace std; const int N = 30005; int pa ; int dis ; int cnt ; int findset(int x){ if(x == pa[x]) return pa[x]; int root = findset(pa[x]); dis[x] += dis[pa[x]]; pa[x] = root; return pa[x]; } int main(){ int p; while(~scanf("%d",&p)){ char op[5]; int a,b; for(int i = 1; i <= N; i++){ pa[i] = i; cnt[i] = 1; dis[i] = 0; } while(p--){ scanf("%s",op); if(op[0] == 'M'){ scanf("%d%d",&a,&b); a = findset(a); b = findset(b); if(a != b){ pa[b] = a; dis[b] = cnt[a]; cnt[a] += cnt[b]; } } else{ scanf("%d",&a); b = findset(a); printf("%d\n",cnt[b]-dis[a]-1); } } } return 0; }
相关文章推荐
- 学习opencv--第一篇:小试牛刀
- 一道华为笔试题
- 总结系列--Android开发规范
- MySQL数据库的常用命令语句记录——数据库及表模式语句
- UVA 658 It's not a Bug, it's a Feature!
- Note For Linux By Jes(7)-学习 shell scripts
- 技术博客是程序猿的不归路。。。
- UIEvent
- 读书笔记之linux/unix系统编程手册(43)
- 集合的基础知识
- MySQL数据库的常用命令语句记录——数据操纵语句及函数
- 信号量例子
- 各浏览器对 document、document.body、document.documentElement 对象的 onscroll 事件支持情况
- Linux的NTP配置总结(转)
- HDU 4280 Island Transport 又一发SAP
- ASCII码(转)
- 追求内心的自由
- QT中QWidget、QDialog及QMainWindow的区别
- 临近的最小数
- Maven安装与Maven HelloWorld入门实例