hdu3635并查集

并查集的题。题意是悟空去收集龙珠,一开始告诉你有t颗龙珠和信息与问题的总数q
然后是q个信息或问题
T A B就是把龙珠A所在的城市中所有龙珠送去B龙珠所在的城市
Q A就是问A龙珠所在的城市地址,该城市的龙珠个数,A龙珠的转移个数

思路:开一个结构体数组,元素代表龙珠,每颗龙珠有两个变量,一个是龙珠的前一颗龙珠的id
一个是所在城市的龙珠个数。
明显,被转移出来的龙珠是不可能回到原来的城市了,相当于该城市的龙珠被转移
这个城市就消失,可以看出,这就是并查集嘛~~!
当龙珠的id或龙珠的最终前驱的id等于城市的id时,就可以得知城市的id;
城市中有多少个龙珠可以再合并时,利用bin[fb].y+=bin[fa].y求出;
至于移动的次数,一开始我是在合并时求的,这是错的,因为没有考虑到当龙珠有后继时,会出
现后继没累加的情况,wa到我吐血!
后来直接在输出答案前,利用不断访问前驱的,求前驱的个数,就是移动的个数了,不过牺牲了时间
345ms 代码如下


#include<iostream>
typedef struct ball{
    int x;
    int y;
}ball;

ball bin[10002];

int merge(int a,int b)
{
    int fa,fb;
    
    for(fb=b;bin[fb].x!=fb;fb=bin[fb].x);
    for(fa=a;bin[fa].x!=fa;fa=bin[fa].x);
    if(fa==fb) return 0;
    
    bin[fa].x=bin[fb].x;
    bin[fb].y+=bin[fa].y;
    return 0;
}


int main(){
    int i,c,a,b,t,q,ans;
    int n,m=0;
    scanf("%d",&n);
    while(n--)
    {
        m++;
        scanf("%d %d",&t,&q);
        printf("Case %d:\n",m);
        for(i=1;i<=t;i++)
        {
            bin[i].x=i;
            bin[i].y=1;
        }
        for(i=0;i<q;i++)
        {
            
            getchar();
            c=getchar();
            if(c=='T')
            {
                scanf("%d %d",&a,&b);
                merge(a,b);
            }
            else
            {  
                int z=0;
                scanf("%d",&a);
                
                for(ans=a;bin[ans].x!=ans;ans=bin[ans].x)
                {
                    z++;
                }
                printf("%d %d %d\n",bin[ans].x,bin[ans].y,z);
            }
        }


    }
    
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值