HDU

题意:1~N个龙珠,放在1~N个城市,有两种操作:T A B 将A所再城市的所有球转移到B所在的城市。 Q X 询问X所在的城市pls,该城市中龙珠数量nm,以及龙珠转移次数trs

题解:并查集模板题,顺带更新一些数据。pls不必更新,因为X所在的集和的根即为城市编号。nm只需在union时将A集合根的nm加到B集合根的nm上,最后输出根的nm。trs则是在每次T中对根++(暂时将操作存在根上),在下次find时,如果某个儿子换根了就更新下去,。。。

ac

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
const int maxn = 1e4 + 5;
struct ball {
    int fa,trs, nm;//place,total num,trans time
}b[maxn];
int find(int x) {
    if (b[x].fa == x)return x;
    else {
        int tmp = b[x].fa;
         b[x]. fa = find(b[x].fa);
         b[x].trs += b[tmp].trs;
         return b[x].fa;
    }
};
void un(int x, int y) {
    int xx = find(x);
    int yy = find(y);
    if (xx != yy) {
        b[xx].fa = yy;
        b[yy].nm += b[xx].nm;
        b[xx].trs++;
    }
    
    
};
int main() {
    int t;
    cin >> t;
    for (int k = 1; k <= t; k++) {
        printf("Case %d:
", k);
        int n, q;
        cin >> n >> q;
        for (int i = 1; i <= n; i++) b[i].nm = 1, b[i].trs= 0,b[i].fa=i;
        for (int i = 1; i <= q; i++) {
            char c[5];
            scanf("%s", c);
            if (c[0] == 'T') {
                int x, y;
                scanf("%d%d", &x, &y);
                un(x, y);
            }
            else {
                int x;
                scanf("%d", &x);
                int xx = find(x);
                printf("%d %d %d
",xx, b[xx].nm, b[x].trs);
                
            }
        }
    }
}
成功的路并不拥挤,因为大部分人都在颓(笑)
原文地址:https://www.cnblogs.com/SuuT/p/8576238.html