hdu3635 Dragon Balls

题意:

初始时,有n个龙珠,编号从1到n,分别对应的放在编号从1到n的城市中。
现在又2种操作:
T A B,表示把A球所在城市全部的龙珠全部转移到B城市。(第一次时,因为A球所在的城市只有一个球,所以只移动1个,如果有多个,则全部移动)。
Q A,表示查询A。要求得到的信息分别是:A现在所在的城市,A所在城市的龙珠数目,A转移到该城市移动的次数(如果没有移动就输出0)

题解:

并查集,需要用到路径压缩,每次移动根结点的移动次数+1,,计算路径是,求子节点的路径加上根结点移动次数即可。

#include <iostream>
using namespace std;
const int maxn = 10005;
struct Node{
    int fa;
    int son;
    int tran;
}p[maxn];
int find(int x){
    if(x==p[x].fa)
        return x;
    int temp = p[x].fa;
    p[x].fa = find(p[x].fa);
    p[x].tran += p[temp].tran;
    return p[x].fa;
}
void join(int x,int y){
    int tx,ty;
    tx = find(x);
    ty = find(y);
    if(tx==ty) return;
    p[tx].fa = ty;
    p[tx].tran++;
    p[ty].son += p[tx].son;
    p[tx].son = 0;
}
int main(){
    int t,n,m,a,b;
    int kase = 0;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            p[i].fa = i;
            p[i].son = 1;
            p[i].tran = 0;
        }
        printf("Case %d:\n",++kase);
        char s[5];
        while(m--){
            scanf("%s",s);
            if(s[0]=='T'){
                scanf("%d%d",&a,&b);
                join(a, b);
            }else{
                scanf("%d",&a);
                int ans = find(a);
                printf("%d %d %d\n",ans,p[ans].son,p[a].tran);
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a1561067921/article/details/77970044
今日推荐