【数据结构】【基础】银河英雄传说
原题:https://www.acwing.com/problem/content/240/
思路:
- 并查集实现:
使用范围:动态维护许多具有传递性的关系,能在无向图中维护节点之间的连通性。
根节点数组p初始化为自己,以及查询根节点函数find
int p[N], d[N];
int find(int x) { if(p[x] != x) { int root = get(p[x]); d[x] += d[p[x]];//权值更新 p[x] = root; } return p[x]; }
- 如何实现题目要求的操作
对于M操作,查询两个元素的根节点,将要移动的根节点赋值为另一个(连接在该列后),然后更新根节点的权值为该列已有元素的个数。为此我们还需要一个size数组来记录根节点的元素数目。
#include<iostream> using namespace std; const int N = 30050; int p[N],d[N],sizex[N],n,m; int get(int x) { if(p[x] != x) { int root = get(p[x]); d[x] += d[p[x]]; p[x] = root; } return p[x]; } int main() { int t; cin >> t; for(int i = 1; i <= N;i ++ ) p[i] = i, sizex[i] = 1; while(t -- ) { char s[2]; int x, y; scanf("%s%d%d",s, &x, &y); if(s[0] == 'M') { x = get(x), y = get(y); d[x] = sizex[y]; sizex[y] += sizex[x]; p[x] = y; } else { int fx = get(x), fy = get(y); if(fx == fy) printf("%d\n",max(0, abs(d[x] - d[y]) - 1)); else printf("-1\n"); } } return 0; }

浙公网安备 33010602011771号