题意: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); } } } }