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:
",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
",fx,count[fx],move[x]);  
            }  
        }  
    }  
    return 0;  
}  

原文地址:https://www.cnblogs.com/forever97/p/3550560.html