标签:
Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:30000KB 64bit IO Format:%lld & %llu
Description
Input
Output
Sample Input
Sample Output
Hint
Description
Input
Output
Sample Input
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
Sample Output
1 0 2 解析见代码:
/* poj1988 ,并查集 题目大意:初始时有N块木块,编号1-N,分开放置, 然后对这些木块开始执行P条操作,M a,b是将a所在的 木块堆移到b所在的木块堆上,C a是查询编号为a的木块在 其之下有多少个木块 思路分析:如果查询的是a号木块所在的木块堆一共有多 少堆,那么这道题就是简单的维护下集合内元素数量就可以,但是现在 问的是它下面有多少块,所以还需要维护的就是它下面的木块数目 初始化under[i]=0,然后对于under数组的更新有两个地方,对于 一个子集的根节点(最下面的木块)在merge时就可以更新了,其他 的木块则是要在压缩路径的时候进行更新,under[i]=under[father[i]] 注意一定要先更新后 压缩路径,要不然就没有更新的效果 */ #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> const int maxn=30000+100; int father[maxn]; int sum[maxn]; int under[maxn]; int findroot(int x) { if(x==father[x]) return x; int t=findroot(father[x]); under[x]+=under[father[x]];//先更新under数组,后压缩路径 father[x]=t; return father[x]; } void merge(int a,int b)//根是在下面的木块 { int pa=findroot(a); int pb=findroot(b); if(pa==pb) return; father[pb]=pa; under[pb]=sum[pa]; sum[pa]+=sum[pb]; } int main() { for(int i=1;i<=maxn;i++) { father[i]=i; sum[i]=1; under[i]=0; } int p; scanf("%d",&p); char s[10]; int a,b; while(p--) { scanf("%s",s); if(s[0]==‘M‘) { scanf("%d%d",&a,&b); merge(b,a); } else { scanf("%d",&a); findroot(a);//祖先节点可能发生了 变化 ,因此需要进行更新 printf("%d\n",under[a]); } } }
标签:
原文地址:http://www.cnblogs.com/xuejianye/p/5699472.html