POJ 1988 Cube Stacking(带权并查集)

来源:互联网 发布:怎么运营好淘宝店铺 编辑:程序博客网 时间:2024/04/28 19:41

Cube Stacking
Time Limit: 2000MS Memory Limit: 30000KTotal Submissions: 23678 Accepted: 8299Case Time Limit: 1000MS

Description

Farmer John and Betsy are playing a game with N (1 <= N <= 30,000)identical cubes labeled 1 through N. They start with N stacks, each containing a single cube. Farmer John asks Betsy to perform P (1<= P <= 100,000) operation. There are two types of operations: 
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

* Line 1: A single integer, P 

* 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

Print the output from each of the count operations in the same order as the input file. 

Sample Input

6M 1 6C 1M 2 4M 2 6C 3C 4

Sample Output

102

Source

USACO 2004 U S Open


题目链接: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;}

0 0
原创粉丝点击