HDU-3635-Dragon Balls(基础带权并查集,求移动次数)

题目
他的国家有N个城市,世界上正好有N个龙珠。首先,对于第i个龙珠,神龙将把它放在第i个城市。经过漫长的岁月,一些城市的龙珠会被运送到其他城市。为了救体力,悟空计划带着飞天雨云,一种神奇的飞天云来收集龙珠。
每次悟空收集一个龙珠的信息,他都会问你那个龙珠的信息。你必须告诉他球在哪个城市,那个城市有多少个龙珠,你还需要告诉他球到目前为止已经运了多少次。

输入

输入的第一行是一个正整数T(0 < T <= 100)。
对于每种情况,第一行包含两个整数:N和Q (2 < N <= 10000, 2 < Q <= 10000)。
以下每一行都包含一个事实或一个问题,格式如下:
所有和A在同一个城市的龙珠都已经被运到了B球所在的城市。你可以假设这两个城市是不同的。
问:悟空想知道X(城中Ath球的id), Y(城中X球的数量),Z(城中Ath球的转运时间)。(1 <= A, B <= N)

输出

对于每个测试用例,输出被格式化为示例输出的测试用例编号。然后,对于每个查询,输出一行带有三个整数(X Y Z)的行,它们之间用空格隔开。

题解:
需要求一个球的移动次数。这就是带权并查集。合并的时候cnt[ra]++;

#include<bits/stdc++.h>
using namespace std;
const int N=10000+5;
int f[N],cnt[N],sum[N];
int seek(int x){
    if(x==f[x]) return x;
    int fa=f[x];
    f[x]=seek(f[x]),cnt[x]+=cnt[fa];
    return f[x];
}
int main(){
    int T,cas=0;scanf("%d",&T);
    while(T--){
        int n,m;scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) f[i]=i,cnt[i]=0,sum[i]=1;
        char ch[3];
        int a,b,x,flag=0;
        while(m--){
            scanf("%s",ch);
            if(ch[0]=='T'){
                scanf("%d%d",&a,&b);int ra=seek(a),rb=seek(b);
                if(ra!=rb) f[ra]=rb,++cnt[ra],sum[rb]+=sum[ra];
            }
            else{
                if(!flag) printf("Case %d:\n",++cas);
                flag=1;
                scanf("%d",&x);int rx=seek(x);
                printf("%d %d %d\n",rx,sum[rx],cnt[x]);
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值