• 【并查集】hdu 3635 Dragon Balls


    题目描述:

    http://acm.hdu.edu.cn/showproblem.php?pid=3635

     

    中文大意:

    日本总共有 n 颗龙珠,被神龙放置在了 n 个城市中。

    T A B :将龙珠 A 所在城市中的所有龙珠运送到龙珠 B 的所在城市。假定这两个城市是不同的。

    Q A   :输出龙珠 X 所在的城市,该市中龙珠的个数以及龙珠 X 的运输次数。 

    思路:

    一个城市就是一个集合,龙珠就是集合中的节点。

    本题的难点在于,如何更新每个龙珠的移动次数。

    在合并操作中,times[x]++; 只是更新了原根节点的移动次数。而非根节点的移动次数并未更新。

    非根节点的移动次数 = 当前节点的移动次数 + 原根节点的移动次数 + ... 

    这个过程,需要利用迭代操作来实现,请结合下面例子自行体会:

    4

    T 1 2

    T 2 3

    T 3 4

    Q 1

     

    代码:

    #include<iostream>
    using namespace std;
    
    int n,q;
    int city[10001];//各龙珠所在城市 
    int times[10001];//各龙珠的移动次数 
    int cnt[10001];//各城市的龙珠个数 
    
    void init(){
        for(int i=1;i<=n;i++){
            city[i] = i;
            times[i] = 0;
            cnt[i] = 1;
        }
    }
    
    //寻找龙珠 x 的所在城市 
    int find(int x){
        if(city[x] == x){
            return x;
        }
        int root = find(city[x]);
        //当前龙珠的移动次数 = 当前龙珠移动次数 + 根节点龙珠移动次数 
        times[x] += times[city[x]];
        city[x] = root;
        return root;
    }
    
    //合并 
    void union_set(int x, int y){
        x = find(x);
        y = find(y);
        
        city[x] = y;
        times[x]++;
        cnt[y] += cnt[x];
    }
    
    int main(){
        int t;
        scanf("%d", &t);
        for(int k=1;k<=t;k++){
            scanf("%d %d", &n, &q);
            init();
            printf("Case %d:
    ",k);
            
            char c;
            int x,y;
            for(int i=0;i<q;i++){
                getchar(); 
                scanf("%c", &c);
                
                if(c == 'T'){
                    scanf("%d %d", &x, &y);
                    union_set(x, y);
                }
                else if(c == 'Q'){
                    scanf("%d", &x);
                    int root = find(x);
                    printf("%d %d %d
    ", root, cnt[root], times[x]);
                }
            }
        }
    }
    作者:老干妈就泡面
    本文版权归作者和博客园共有,欢迎转载,但请给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    字符串与Unicode码的相互转换
    关于es6中的yield
    ajax请求中的6个全局事件
    用H5上传文件
    类型化数组
    git笔记-9-29
    js正则表达式验证身份证号和密码
    assertThat用法
    java产生随机数的几种方式
    jQuery之Deferred对象详解
  • 原文地址:https://www.cnblogs.com/bjxqmy/p/14483898.html
Copyright © 2020-2023  润新知