并查集的题。题意是悟空去收集龙珠,一开始告诉你有t颗龙珠和信息与问题的总数q
然后是q个信息或问题
T A B就是把龙珠A所在的城市中所有龙珠送去B龙珠所在的城市
Q A就是问A龙珠所在的城市地址,该城市的龙珠个数,A龙珠的转移个数
思路:开一个结构体数组,元素代表龙珠,每颗龙珠有两个变量,一个是龙珠的前一颗龙珠的id
一个是所在城市的龙珠个数。
明显,被转移出来的龙珠是不可能回到原来的城市了,相当于该城市的龙珠被转移
这个城市就消失,可以看出,这就是并查集嘛~~!
当龙珠的id或龙珠的最终前驱的id等于城市的id时,就可以得知城市的id;
城市中有多少个龙珠可以再合并时,利用bin[fb].y+=bin[fa].y求出;
至于移动的次数,一开始我是在合并时求的,这是错的,因为没有考虑到当龙珠有后继时,会出
现后继没累加的情况,wa到我吐血!
后来直接在输出答案前,利用不断访问前驱的,求前驱的个数,就是移动的个数了,不过牺牲了时间
345ms 代码如下
#include<iostream> typedef struct ball{ int x; int y; }ball; ball bin[10002]; int merge(int a,int b) { int fa,fb; for(fb=b;bin[fb].x!=fb;fb=bin[fb].x); for(fa=a;bin[fa].x!=fa;fa=bin[fa].x); if(fa==fb) return 0; bin[fa].x=bin[fb].x; bin[fb].y+=bin[fa].y; return 0; } int main(){ int i,c,a,b,t,q,ans; int n,m=0; scanf("%d",&n); while(n--) { m++; scanf("%d %d",&t,&q); printf("Case %d:\n",m); for(i=1;i<=t;i++) { bin[i].x=i; bin[i].y=1; } for(i=0;i<q;i++) { getchar(); c=getchar(); if(c=='T') { scanf("%d %d",&a,&b); merge(a,b); } else { int z=0; scanf("%d",&a); for(ans=a;bin[ans].x!=ans;ans=bin[ans].x) { z++; } printf("%d %d %d\n",bin[ans].x,bin[ans].y,z); } } } return 0; }
转载于:https://blog.51cto.com/8590696/1358852