hdu 3635 Dragon Balls(并查集)

来源:互联网 发布:网络图书检索网站 编辑:程序博客网 时间:2024/05/06 04:58

题目是给出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 Ballsmeaning: 经过几次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 10006int 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的numpre[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;}




原创粉丝点击