题目是给出N座城市,(第i个城市有ith龙珠),Q个操作:T A B :表示把Ath球在的城市的所有球搬到Bth球在的城市. Q A表示查询Ath球所在城市的编号X,以及X城市的球数Y,还有A球移动的次数Z....
求移动次数,是要A球移动+A求父亲移动次数+...这样可以在路径压缩时处理.其他都好求.
可是,,可是T_T WA。。。泪啊最后还是芒果大神发现了我的错误/////
/* Problem ID:E - Dragon Balls meaning: 经过几次T(A球所在城市全部的龙珠全部转移到B城市)后,求出A球所在的城市X,以及X城市球的数量,以及A球移动的次数。 Analyzing:并查集, */ #include <iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<vector> using namespace std; typedef struct even{int pi,di;}even; #define FOR(i,s,t) for(int i=(s); i<(t); i++) #define LL long long #define maxn 10006 int num[maxn],pre[maxn],fa;//num:x转移到pre[x]的步数. int T,N,Q; void init(){ FOR(i,0,maxn) {num[i]=0;pre[i]=-1;} } int find(int x){ int s; if(pre[x]<0) return x; s=find(pre[x]); int tmp=pre[x]; num[x]+=num[tmp]; pre[x]=s; return s; } /* num表示的是从x转移到pre[x]用的步数 我们更新要变成x转移到s用的步数 而原来那样写只是x转移到pre[tmp]的步数 所以更新步数我们要从顶层更新,因为不大好写,我就改成递归的了 就是要pre[x]的num更新完才能更新x的num pre[x]还没更新完,就去加了会出错. */ /* int find(int x){ int s; for(s=x;pre[s]>=0;s=pre[s]); while(s!=x){ int tmp=pre[x]; num[x]+=num[tmp]; pre[x]=s; x=tmp; } return s; } */ void Union(int R1,int R2){ int r1=find(R1);//A int r2=find(R2);//B A->B if(r1==r2) return; pre[r2]+=pre[r1]; pre[r1]=r2; num[r1]=1; } void Query(int A){ int X,Y,Z; X=find(A);Y=pre[X];Z=num[A]; printf("%d %d %d\n",X,-Y,Z);//移动几次 } int main(){ char op[3]; int Cas=1; int A,B; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&Q); init(); printf("Case %d:\n",Cas++); while(Q--){ scanf("%s%d",op,&A); if(op[0]=='T') {scanf("%d",&B);Union(A,B);} else Query(A); } } return 0; }