标签:并查集
6 M 1 6 C 1 M 2 4 M 2 6 C 3 C 4
1 0 2
这题也是带权并查集,设三个数组pre[i],num[i](代表i所在集合的数字总数),root[i]表示i下面的数字总数。每次移动时输入两个数a,b,因为移动过程中a所在的所有数都移动到b所在集合所有数的上面,所以令a的祖先t1的父亲为b的祖先t2,这样下面递归的时候,root[i]可以递归相加。
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<algorithm> #include<map> #include<string> using namespace std; char s[10]; int pre[30005],num[30005],root[30005]; int find(int x) { int temp; if(pre[x]==x)return x; temp=pre[x]; pre[x]=find(pre[x]); root[x]+=root[temp]; return find(pre[x]); } int main() { int p,i,m,j,a,b,t1,t2; while(scanf("%d",&p)!=EOF) { for(i=0;i<=30005;i++){ pre[i]=i;num[i]=1;root[i]=0; } while(p--) { scanf("%s",s); if(s[0]=='M'){ scanf("%d%d",&a,&b); t1=find(a);t2=find(b); if(t1==t2)continue; pre[t1]=t2; root[t1]+=num[t2]; num[t2]+=num[t1]; } else if(s[0]=='C'){ scanf("%d",&a); t1=find(a); printf("%d\n",root[a]); } } } return 0; }
标签:并查集
原文地址:http://blog.csdn.net/kirito_acmer/article/details/45691445