hdu3635 Dragon Balls

题目链接如下:

Problem - 3635

这里介绍三种处理转移次数的方法,都是并查集的思路。

进行T x y的时候,即把x所在地的全部搬到y所在地。如何更新x里边的龙珠的转移次数呢?

思路一:

在把x集合合并到y的集合之前,将节点的根是rootx的节点的转移次数加一,这样每次都会有nlogn的开销,然后总的开销最坏是qnlogn,直接爆炸。

思路二:

不进行路径压缩,直接向上查找根节点,记录向上查找的次数。这个次数其实就是移动的次数了。

这个时间复杂度大概最坏是qn,刚刚好的样子。也确实能过。

思路三:

进行路径压缩,当遇到T x y的操作时,只将x的根节点的次数加一,并且进行路径压缩。这样的好处是,在find的同时也更新路径上节点的转移次数,这里所有之前的节点存储的是累计转移次数,时间复杂度是qlogn。

代码如下所示:

#include<cstdio>
#include<queue>
#include<stack>
#include<map>
#include<list>
#include<vector>
#include<string>
#include<iostream>
#include<ctime>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>

using namespace std;

const int MAXN = 10001;
struct node{
    int f;
    int times;
    int num;
}s[MAXN];
int x,y;
int n,q,t;
char op;

void init_s(){
    for (int i = 1; i <= n; ++i) {
        s[i].f=i;
        s[i].times=0;
        s[i].num=1;
    }
}

int find_s(int x){
    if (s[x].f==x) return x;
    int tmp=s[x].f;
    s[x].f=find_s(s[x].f);
    s[x].times+=s[tmp].times;
    return s[x].f;
}

void union_s(int x,int y){
    int rootx= find_s(x);
    int rooty= find_s(y);
    if (rootx!=rooty){
        s[rootx].f=rooty;
        s[rooty].num+=s[rootx].num;
        s[rootx].times++;
    }
}

int main() {
    scanf("%d", &t);
    for (int k = 1; k <= t; ++k) {
        scanf("%d %d", &n, &q);
        init_s();
        printf("Case %d:\n", k);
        for (int i = 0; i < q; ++i) {
            getchar();
            scanf("%c", &op);
            if (op == 'T') {
                scanf("%d %d", &x, &y);
                union_s(x, y);
            } else {
                scanf("%d", &x);
                int root = find_s(x);
                printf("%d %d %d\n", root, s[root].num, s[x].times);
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值