POJ 1988 Cube stacking
题意:
有N(N<=30,000)堆方块,开始每堆都是一个方块。方块编号1 –N. 有两种操作:
M x y :表示把方块x所在的堆,拿起来叠放到y所在的堆上。
C x : 问方块x下面有多少个方块。
操作最多有P (P<=100,000)次。对每次C操作,输出结果。
分析:
用并查集解。
此题除了parent数组,还要开设sum数组:记录每堆一共有多少方块。
若parent[a] = a, 则sum[a]表示a所在的堆的方块数目。
under数组,under[i]表示第i个方块下面有多少个方块。
under数组在 堆合并 和 路径压缩的时候都要更新。
code:
#include <stdio.h> #include <string.h> #define MAXN 30005 int p[MAXN], sum[MAXN], under[MAXN]; int Getparent(int x) { if(p[x]==x) return x; int t=Getparent(p[x]); under[x] +=under[p[x]]; p[x] = t; return p[x]; } void Merge(int a, int b) { int px = Getparent(a); int py = Getparent(b); p[px] = py; under[px] = sum[py]; sum[py] +=sum[px]; } int main() { int i, P, a, b; char s[10]; for(i=0; i<MAXN; i++) { p[i] = i; sum[i] = 1; under[i] = 0; } scanf("%d",&P); for(i=0; i<P; i++) { scanf("%s",s); if(s[0]=='M') { scanf("%d%d",&a,&b); Merge(a,b); } else { scanf("%d",&a); Getparent(a); printf("%d\n",under[a]); } } return 0; }