POJ 1988 Cube Stacking

来源:互联网 发布:it技术博客 知乎 编辑:程序博客网 时间:2024/06/06 00:06

题目大意:

        有一堆完全相同的立方体,总共有N个(1 ≤ N ≤ 30,000),编号为1 ~ N,刚开始时每个立方体各自成一堆(即每堆只有一个立方体),现有两种操作,第一种是"M X Y",意思是将编号X立方体所在的堆原模原样叠放在Y所在堆的顶上,第二种操作是"C X“,意思是要求你输出X立方体下面有多少个立方体。

        现只有一个测例,开始时会给给出操作数P(1 ≤ P ≤ 100,000),接下来按照顺序逐个给出操作,但是输入中并不给出N,输入保证不会出现将一个堆堆在自己顶上的操作,按要求输出每次"C"询问即可。

题目链接

注释代码:

/*                * Problem ID : POJ 1988 Cube Stacking    * Author     : Lirx.t.Una                * Language   : C++           * Run Time   : 282 ms                * Run Memory : 332 KB               */#include <stdio.h>//立方体的最大数量#defineMAXN30000shortfath[MAXN + 1];//并查集,范围不超过short//表示以i为根的树上结点个数//树根存放的永远都是叠在最底下的那个方块//由于总数不超过立方体总数,因此范围也不超过shortshortsum[MAXN + 1];//关系,under[i]表示i和fath[i]之间方块的数量//有时这个数量不包括i和fath[i]这两个//有时这个数量就是最终的答案//当没有路径压缩是是前一种//当路径压缩后数量就是后一种shortunder[MAXN + 1];intfind(int x) {intfx;introot;if ( x == fath[x] ) return x;//先进行路径压缩,此操作保证fx和根的关系是正确的//并且fx已经被路径压缩过了,因此under[fx]就是正确答案root = find( fx = fath[x] );//再将x也接在根上,但是在这之前需要将x和gen之间的关系//进行更新,只要通过x和fx的关系以及fx和根之间的关系就//可以传递出x和根之间的关系了under[x] += under[fx];return fath[x] = root;//最后再将x接在根上}voidmerge( int x, int y ) {intfx, fy;fx = find(x);fy = find(y);if ( fx != fy ) {fath[fx]   = fy;//将fx叠在fy所在堆上//由于fx直接接在fy上了,因此相当于对fx进行了路径压缩//所以fx和fy之间的关系应该正确反映fx之下有多少个立方体//因此under[fx]应该就是正确答案under[fx]  = sum[fy];sum[fy]   += sum[fx];//再将fy堆的总数量进行更新累加}}intmain() {intp;//询问次数charcmd;intx, y;//接受临时立方体编号inti;for ( i = 1; i <= MAXN; i++ ) {//初始化fath[i] = i;sum[i]  = 1;}scanf("%d", &p);while ( p-- ) {scanf("\n%c", &cmd);switch (cmd) {case 'M' :scanf("%d%d", &x, &y);merge( x, y );break;case 'C' :scanf("%d", &i);find(i);//先进行路径压缩,使i接到树根上printf("%d\n", under[i]);break;default : break;}}return 0;}
无注释代码:

#include <stdio.h>#defineMAXN30000shortfath[MAXN + 1];shortsum[MAXN + 1];shortunder[MAXN + 1];intfind(int x) {intfx;introot;if ( x == fath[x] ) return x;root = find( fx = fath[x] );under[x] += under[fx];return fath[x] = root;}voidmerge( int x, int y ) {intfx, fy;fx = find(x);fy = find(y);if ( fx != fy ) {fath[fx]   = fy;under[fx]  = sum[fy];sum[fy]   += sum[fx];}}intmain() {intp;charcmd;intx, y;inti;for ( i = 1; i <= MAXN; i++ ) {fath[i] = i;sum[i]  = 1;}scanf("%d", &p);while ( p-- ) {scanf("\n%c", &cmd);switch (cmd) {case 'M' :scanf("%d%d", &x, &y);merge( x, y );break;case 'C' :scanf("%d", &i);find(i);printf("%d\n", under[i]);break;default : break;}}return 0;}
单词解释:

verify:vt, 核实,查证

Bessie:贝西(女子名)

cube:n, 立方体

identical:adj, 同一的,完全相同的

Betsy:贝奇(女子名,等于Elizabeth)

0 0
原创粉丝点击