poj1988cube stacking(并查集)
2016-07-22 09:52
351 查看
题意:有最多30000个编号为1~30000的箱子,将每个箱子当做一个栈,对这些箱子进行p次操作,每次操作分别为以下两种之一:
1>输入 M x y:表示将编号为x的箱子所在的栈放在编号为y的箱子所在栈的栈顶.
2>输入 C x:计算编号为x的所表示的栈中在x号箱子下面的箱子数目.
这道我想了两天都没想出来,刚接触并查集,完全没想到(弱爆了)在find中使用递归(之前看的都是用循环写的)。
如果下面的代码看不懂可先看并查集的递归写法
这两句是最精华的,主要思考这两句话
1>输入 M x y:表示将编号为x的箱子所在的栈放在编号为y的箱子所在栈的栈顶.
2>输入 C x:计算编号为x的所表示的栈中在x号箱子下面的箱子数目.
这道我想了两天都没想出来,刚接触并查集,完全没想到(弱爆了)在find中使用递归(之前看的都是用循环写的)。
如果下面的代码看不懂可先看并查集的递归写法
int find(int node) { if(pre[node]==node) return node; return pre[node]=find(pre[node]); } void join(int x,int y) { int fx=find(x),fy=find(y); if(fx!=fy) pre[fx]=fy; }
pre[node]=find(tmp); place[node]+=place[tmp];
这两句是最精华的,主要思考这两句话
#include <iostream> #include <stdio.h> #include <string.h> #include <algorithm> #define ms(X) memset(X,0,sizeof(X)) #define msc(X) memset(X,-1,sizeof(X)) typedef long long LL; using namespace std; int pre[30005],sum[30005],place[30005]; int find(int node) { if(pre[node]==-1) return node; int tmp=pre[node]; pre[node]=find(tmp);// place[node]+=place[tmp];// return pre[node]; } void join(int x,int y) { int fx=find(x),fy=find(y); pre[fx]=fy; place[fx]+=sum[fy]; sum[fy]+=sum[fx]; } int main() { int P; cin>>P; msc(pre); ms(place); for(int i=1;i<=30000;i++) sum[i]=1; while(P--) { char ss[3]; int a,b; scanf("%s",ss); if(ss[0]=='M'){ scanf("%d %d",&a,&b); join(a,b); } else { scanf("%d",&a); find(a); printf("%d\n",place[a]); } } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题