对并查集的扩展.看了下解题报告,总算有想法了.
sum[i]记录根结点i下面的结点数(包括自己)和up[i]记录在某结点i上面的结点数.则在一结点m之下的结点数为sum[findpar(m)]-up[m]-1 (findpar查找根结点)
在uni和findpar过程中更新sum和up的内容.(蓝色部分)
- #include "stdio.h"
- const int max_node=30005;
- int par[max_node+1];
- int up[max_node+1];
- int sum[max_node+1];
- int add;
- int findpar(int num){
- int top;
- if(par[num]!=num){
- top=findpar(par[num]);
- if(top!=par[num]){
- up[num]+=add;
- }
- add=up[num];
- par[num]=top;
- return top;
- }
- return num;
- }
- void uni(int a,int b){
- a=findpar(a);
- b=findpar(b);
- par[b]=a;
- up[b]=sum[a];
- sum[a]+=sum[b];
- }
- int main()
- {
- // freopen("1.in","r",stdin);
- int p;
- scanf("%d",&p);
- while(getchar()!='/n');
- int s,d;
- char c;
- int i;
- for(i=0;i< =max_node;++i){
- par[i]=i;
- up[i]=0;
- sum[i]=1;
- }
- while(p-->0){
- c=getchar();
- if(c=='M'){
- scanf("%d %d",&s,&d);
- while(getchar()!='/n');
- uni(s,d);
- }
- else{
- scanf("%d",&d);
- while(getchar()!='/n');
- printf("%d/n",sum[findpar(d)]-up[d]-1);
- }
- }
- return 0;
- }