hdu 3635 并查集

题意:有n个球在n个城市,刚开始,1号球在1号城市,依次2号球在2号城市。

有两种操作,T  A B 将A球所在城市的球全部移到B球所在城市。

   Q   A  查询A所在的城市,A求移动的次数,A所在城市的球的总数。

并查集主要是路径压缩时,更改 移动的次数。如 子节点的移动次数等于加等于父节点的次数

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define FF  freopen("Input.txt","r",stdin)
#define mem(x,y) memset(x,y,sizeof(x))
struct Node
{
    int father;//根节点
    int num;//球的个数
    int tranport;//转移次数
}p[10200];
void init(int n)
{
    for(int i=0;i<=n;i++)
    {
        p[i].father=i;
        p[i].tranport=0;
        p[i].num=1;
    }
}
int find(int x)
{
    int tmp=p[x].father;
    if(x!=p[x].father)
        p[x].father=find(tmp);
    p[x].tranport+=p[tmp].tranport;//路径压缩时改变
    return p[x].father;            //每个球的移动次数.
}
void Union(int x,int y)
{
    x=find(x);
    y=find(y);
    if(x==y) return ;
    p[x].father=y;
    p[y].num+=p[x].num;
    p[x].tranport++;
    p[x].num=0;
}
int main()
{
    //FF;
    int ncase,n,m,t=1,i,j;
    char str[5];
    scanf("%d",&ncase);
    while(ncase--)
    {
        scanf("%d%d",&n,&m);
        init(n);
        printf("Case %d:\n",t++);
        while(m--)
        {
           scanf("%s",str);
           if(str[0]=='T')
           {
               scanf("%d%d",&i,&j);
               Union(i,j);
           }
           else
           {
               scanf("%d",&j);
               i=find(j);
               printf("%d %d %d\n",i,p[i].num,p[j].tranport);
           }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值