1 #include<cstdio> 2 #include<cstdlib> 3 int T,x,y,p[30001],a[30001],r[30001]; //r[i]表示i号战舰和它的队头战舰之间的距离 4 char ch[2]; //a[i]是代表为i的队一共有多少战舰 5 void init(){ //实际上,如果用r[x]表示数目的话对于只有一个结点和两个结点的情况 6 for(int i=1;i<=30000;i++) //就不好区分,设为距离可以便于统一处理 7 p[i]=i,a[i]=1; //为什么需要a[],因为每次UNION操作是把队列置于另一个队列的队尾 8 } //为了得到两个队头的距离,就需要有这样的记录 9 int find(int x){ //始终注意到,UNION本质是对“代表元素”的操作 10 if(x!=p[x]){ 11 int px=find(p[x]);//找到当前结点x的根节点,同时在x以上的结点都完成了r[x]的更新,包括r[p[x]] 12 r[x]+=r[p[x]]; //加上距离得到当前结点x对根节点px的距离 13 p[x]=px; 14 } 15 return p[x]; 16 } 17 void Union(int x,int y,int px,int py){ 18 p[px]=py; //直接设px指向py 19 r[px]=a[py]; //那么此时px和py之间的距离就是py队列的元素数目 20 a[py]+=a[px]; //因为实际上是把px置于py队尾,那么py队列现在的数目就是两者之和 21 } 22 int main() 23 { 24 init(); 25 scanf("%d",&T); 26 while(T--){ 27 scanf("%s%d%d",ch,&x,&y); 28 int px=find(x),py=find(y); 29 if(ch[0]=='M') Union(x,y,px,py); 30 else{ 31 if(px!=py) printf("-1 "); 32 else printf("%d ",abs(r[x]-r[y])-1); //数目=距离-1 33 } 34 } 35 }