HDU 3635 Dragon Balls

题解:做到一种并查集的新题型,在状态压缩的时候传递祖先的信息,每个根结点都是最多移动一次的,所以记录移动次数把自己的加上父亲结点的就是移动总数了。

#include <cstdio>   

#include <cstring> 

const int MAXN=10010;  

int n,q,count[MAXN],f[MAXN],move[MAXN];  

int sf(int x){  

    if(f[x]==x) return x;  

    int t=f[x];

    f[x]=sf(f[x]);  

    move[x]+=move[t];  

    return f[x];  

}  

void Union(int x,int y){  

    x=sf(x);  

    y=sf(y);  

    if(x!=y){  

        f[x]=y;  

        count[y]+=count[x];  

        move[x]=1;  

    }  

}  

int main(){  

    int T;  

    scanf("%d",&T);  

    int cas=1;  

    while(T--){  

        scanf("%d%d",&n,&q);   

        for(int i=1;i<=n;i++)count[i]=1;  

        for(int i=1;i<=n;i++)f[i]=i;  

        memset(move, 0, sizeof(move));  

        char str[10];  

        printf("Case %d:\n",cas++);  

        for(int i=1;i<=q;i++){  

            scanf("%s",str);  

            if(str[0]=='T'){  

                int x,y;  

                scanf("%d%d",&x,&y);  

                Union(x,y);  

            }  

            else{  

                int x;  

                scanf("%d",&x);  

                int fx=sf(x);  

                printf("%d %d %d\n",fx,count[fx],move[x]);  

            }  

        }  

    }  

    return 0;  

}  



你可能感兴趣的:(drag)