hdu 2818 Building Block (带权并查集,很优美的题目)
2015-09-01 22:09
417 查看
[align=left]Problem Description[/align]
[align=left]Input[/align]
[align=left]Output[/align]
[align=left]Sample Input[/align]
[align=left]Sample Output[/align]
[align=left]Source[/align]
2009 Multi-University Training Contest 1 - Host by TJU
题目大意:有N个piles(按序编号),每次有两种操作:
M x y表示把x所在的那一堆全部移到y所在的那一堆
C x 询问在x之下有多少个方块
解决方法:使用并查集(路径压缩)实现,然后用count[X]表示X所在的那一堆总共多少个piles,under[x]表示x之下有多少个piles。
首先,每次操作我们合并两个集合(如果原来在同一集合中除外),count[X]是每次操作可以直接实现的,就是把两堆的数目相加,很容易(初始值为1)。那么当某次移动操作发生时,首先确定x所在的那一堆最底部的X以及y所在那一堆最底部的Y,那么under[X]的数目就是另外一堆piles的总数count[Y],有了这个条件,在接下去的操作中,就可以根据FIND(x)递归去一边寻找根一边更新其他未知的under[x]。
View Code
[align=left]Recommend[/align]
John are playing with blocks. There are N blocks (1 <= N <= 30000) numbered 1...N。Initially, there are N piles, and each pile contains one block. Then John do some operations P times (1 <= P <= 1000000). There are two kinds of operation: M X Y : Put the whole pile containing block X up to the pile containing Y. If X and Y are in the same pile, just ignore this command. C X : Count the number of blocks under block X You are request to find out the output for each C operation.
[align=left]Input[/align]
The first line contains integer P. Then P lines follow, each of which contain an operation describe above.
[align=left]Output[/align]
Output the count for each C operations in one line.
[align=left]Sample Input[/align]
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
[align=left]Sample Output[/align]
1 0 2
[align=left]Source[/align]
2009 Multi-University Training Contest 1 - Host by TJU
题目大意:有N个piles(按序编号),每次有两种操作:
M x y表示把x所在的那一堆全部移到y所在的那一堆
C x 询问在x之下有多少个方块
解决方法:使用并查集(路径压缩)实现,然后用count[X]表示X所在的那一堆总共多少个piles,under[x]表示x之下有多少个piles。
首先,每次操作我们合并两个集合(如果原来在同一集合中除外),count[X]是每次操作可以直接实现的,就是把两堆的数目相加,很容易(初始值为1)。那么当某次移动操作发生时,首先确定x所在的那一堆最底部的X以及y所在那一堆最底部的Y,那么under[X]的数目就是另外一堆piles的总数count[Y],有了这个条件,在接下去的操作中,就可以根据FIND(x)递归去一边寻找根一边更新其他未知的under[x]。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; #define N 30006 int fa ; int under ;//下边的个数 int cnt ;//所在堆的堆个数 void init(){ for(int i=0;i<N;i++){ fa[i]=i; under[i]=0; cnt[i]=1; } } int find(int son){ if(fa[son]!=son){ int t=find(fa[son]); under[son]+=under[fa[son]]; fa[son]=t; } return fa[son]; //return fa[x]==x?x:fa[x]=find(fa[x]); } void merge(int x,int y){ int root1=find(x); int root2=find(y); if(root1==root2)return; under[root1]=cnt[root2]; cnt[root2]+=cnt[root1]; fa[root1]=root2; } int main() { int n; while(scanf("%d",&n)==1){ init(); char s[3]; int x,y; for(int i=0;i<n;i++){ scanf("%s",s); if(s[0]=='M'){ scanf("%d%d",&x,&y); merge(x,y); } else{ scanf("%d",&x); find(x); printf("%d\n",under[x]); } } } return 0; }
View Code
[align=left]Recommend[/align]
相关文章推荐
- 将UIView加载成WevView(不懂的可以留言)
- UI中常用的4种传值
- Win10开发:视觉状态VisualState与自适应UI
- UITabBar 自定义
- AbstractQueuedSynchronizer实现原理
- UVALive 4287 Proving Equivalence (强连通分量)
- Android UI设计(引导界面):ViewPager之基本用法
- java基础-GUI
- [DP!]UESTC 890
- LeetCode之Repeated DNA Sequences
- UI_UIGestureRecognizer(触摸手势)
- UINavigationController视图控制器
- iPhone第三节:UITableView(2)
- HDU 4893(Wow! Such Sequence!-线段树单点修改+区间求和+改为最近Fib数)
- InputFormat到key-value生成流程
- iPhone第三节:UITableView
- UIProgressView 进度条
- Codeforces 52A 123-sequence
- UITableView<三>
- UGUI基本控件(二)