POJ 1988 Cube Stacking(带权并查集)
| Time Limit: 2000MS | Memory Limit: 30000K | |
| Total Submissions: 23678 | Accepted: 8299 | |
| Case Time Limit: 1000MS | ||
Description
moves and counts.
* In a move operation, Farmer John asks Bessie to move the stack containing cube X on top of the stack containing cube Y.
* In a count operation, Farmer John asks Bessie to count the number of cubes on the stack with cube X that are under the cube X and report that value.
Write a program that can verify the results of the game.
Input
* Lines 2..P+1: Each of these lines describes a legal operation. Line 2 describes the first operation, etc. Each line begins with a 'M' for a move operation or a 'C' for a count operation. For move operations, the line also contains two integers: X and Y.For
count operations, the line also contains a single integer: X.
Note that the value for N does not appear in the input file. No move operation will request a move a stack onto itself.
Output
Sample Input
6
M 1 6
C 1
M 2 4
M 2 6
C 3
C 4
Sample Output
1
0
2
Source
题目链接:POJ 1988
以前看了很久的题解但是完全看不懂,也是最近会了食物链之后才做的。
既然食物链可以用数值代表关系,那这题只要把取模去掉就可以用数值node[x].up代表自己与祖节点之间的砖块数(不包括本身),然后还有一个问题就是还要知道自己所在砖块堆的总个数node[fx].total(fx是此砖块堆的祖节点即代表)。
那统计up用食物链的思想比较简单就可以做到,关键就是total怎么算,可以设想(画图更好理解),把砖a所在堆放到砖b所在堆,那node[fa].total肯定增加了node[fb].total个,然后node[fa].up显然不变(实际上祖节点就是堆的最上面那块砖的号码),node[fb].total就不要动了,因为只有祖节点才能具有记录total的功能,fb此时已沦为fa下面的一个子节点,node[fb].up还是可以动的,即增加了node[fa].total个。然后这题就差不多解决了,最后输出的时候用本堆砖块数total-本砖块上面的砖块数up-1,减1是因为题目要求只算压在自己这块砖下面的,自己当然不算
代码:
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=300010;
struct info
{
int pre;
int up;
int total;
};
info node[N];
void init(int n)
{
for (int i=0; i<=n; ++i)
{
node[i].pre=i;
node[i].up=0;
node[i].total=1;
}
}
int find(int n)
{
if(node[n].pre==n)
return n;
int tpre=node[n].pre;
node[n].pre=find(node[n].pre);
node[n].up=node[n].up+node[tpre].up;
return node[n].pre;
}
void joint(int a,int b)
{
int fa=find(a),fb=find(b);
if(fa!=fb)
{
node[fb].pre=fa;
node[fb].up+=node[fa].total;
node[fa].total+=node[fb].total;
}
}
int main(void)
{
int n,i,j,a,b,x;
char ops[3];
while (~scanf("%d",&n))
{
init(n);
for (i=0; i<n; ++i)
{
scanf("%s",ops);
if(ops[0]=='M')
{
scanf("%d%d",&a,&b);
joint(a,b);
}
else
{
scanf("%d",&x);
int fx=find(x);
printf("%d\n",node[fx].total-node[x].up-1);
}
}
}
return 0;
}
POJ 1988 Cube Stacking(带权并查集)的更多相关文章
- POJ 1988 Cube Stacking(带权并查集)
哈哈,一次AC. 题意:给你 1-n 编号的立方体,然后移动包含指定编号的立方体的堆移到另一个堆上边, 询问指定的编号立方体下面有多少个立方体. 思路:由于并查集是存储的是它的父亲,那么只能从父亲那里 ...
- poj1988 Cube Stacking 带权并查集
题目链接:http://poj.org/problem?id=1988 题意:有n个方块,编号为1-n,现在存在两种操作: M i j 将编号为i的方块所在的那一堆方块移到编号为j的方块所在的那 ...
- USACO2004 cube stacking /// 带权并查集 oj1302
题目大意: 以N ( 1 ≤ N ≤ 30,000 )个堆栈开始,每个堆栈包含一个单独的立方体.执行P(1≤ P ≤100,000)的操作. 有两种类型的操作:移动和计数. *在移动操作中,将 包含方 ...
- POJ 1773 Parity game 带权并查集
分析:带权并查集,就是维护一堆关系 然后就是带权并查集的三步 1:首先确定权值数组,sum[i]代表父节点到子节点之间的1的个数(当然路径压缩后代表到根节点的个数) 1代表是奇数个,0代表偶数个 2: ...
- POJ 1182 食物链 【带权并查集】
<题目链接> 题目大意: 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我 ...
- POJ 1182 食物链 (带权并查集)
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 78551 Accepted: 23406 Description ...
- POJ 1182 食物链 【带权并查集/补集法】
动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物,以1-N编号.每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种.有人用两种说 ...
- POJ 1733 Parity game (带权并查集)
题意:有序列A[1..N],其元素值为0或1.有M条信息,每条信息表示区间[L,R]中1的个数为偶数或奇数个,但是可能有错误的信息.求最多满足前多少条信息. 分析:区间统计的带权并查集,只是本题中路径 ...
- poj 1182 食物链【带权并查集】
设相等的边权为0,吃的边权为,被吃的边权为2,然后用带权并查集在%3的意义下做加法即可 关系为简单环的基本都可以用模环长的方式是用带权并查集 #include<iostream> #inc ...
- A Bug's Life POJ - 2492 (种类或带权并查集)
这个题目的写法有很多,用二分图染色也可以写,思路很好想,这里我们用关于并查集的两种写法来做. 题目大意:输入x,y表示x和y交配,然后判断是否有同性恋. 1 带权并查集: 我们可以用边的权值来表示一种 ...
随机推荐
- 一台机器开2个Tomcat修改端口号
修改一个Tomcat端口号步骤:1.找到Tomcat目录下的conf文件夹2.进入conf文件夹里面找到server.xml文件3.打开server.xml文件4.在server.xml文件里面找到下 ...
- LINUX下安装TeamViewer
https://www.teamviewer.com/zhcn/download/linux/ [root@ok teamviewer]# yum install -y teamviewer_11.0 ...
- md5sum 生成 经md5加密后的字符串
➜ ~ echo -n 'admin' | md5sum 21232f297a57a5a743894a0e4a801fc3 - ➜ ~ md5sum -h md5sum: invalid option ...
- 动态调用Webservice 支持Soapheader身份验证(转)
封装的WebserviceHelp类: using System; using System.CodeDom; using System.CodeDom.Compiler; using System. ...
- android 检测sqlite数据表中字段(列)是否存在 (转)
原文摘自 http://www.tuicool.com/articles/jmmMnu 一般数据库升级时,需要检测表中是否已存在相应字段(列),因为列名重复会报错.方法有很多,下面列举2种常见的方式: ...
- jq生成目录文件树jQuery Ztree基本用法
转自:http://www.cnblogs.com/linjiqin/p/4547452.html 1.首先在页面上有<ul/>标签 ? 1 <ul id="tree&qu ...
- SU suamp命令学习
- 其他主流开源硬件简介BeagleBone Black快速入门
其他主流开源硬件简介BeagleBone Black快速入门 1.3 其他主流开源硬件简介 开源硬件种类繁多,但主要有两款开源硬件常与BeagleBone比较.它们就是Arduino和Raspberr ...
- DP(01背包) UESTC 1218 Pick The Sticks (15CCPC C)
题目传送门 题意:长度为L的金条,将n根金棍尽可能放上去,要求重心在L上,使得价值最大,最多有两条可以长度折半的放上去. 分析:首先长度可能为奇数,先*2.然后除了两条特殊的金棍就是01背包,所以dp ...
- ZOJ 3911 Prime Query ZOJ Monthly, October 2015 - I
Prime Query Time Limit: 1 Second Memory Limit: 196608 KB You are given a simple task. Given a s ...