UV 11987, uva11987
Ultraviolet A 11987-Almost Union-Find
Question Link
For a given set, operation 1 is the merging set, operation 2 is to move one element of the set to another set, and operation 3 is to output the number and sum of the set.
Train of Thought: Check the set. The key lies in operation 2. to check and query the set, remove a node. If the node is not the root node, it is easy to do so. Then open n more nodes, the father of each node is its I + n at the beginning, so that when moving, there is no need to worry that he is the root node, and the rest is the normal weighted and query set.
Code:
#include <cstdio>#include <cstring>const int N = 200005;int n, m, parent[N], num[N], sum[N];int find(int x) { return x == parent[x] ? x : parent[x] = find(parent[x]);}void init() { for (int i = 0; i <= n; i++) {parent[i] = parent[i + n] = i + n;sum[i] = sum[i + n] = i;num[i] = num[i + n] = 1; }}int main() { while (~scanf("%d%d", &n, &m)) {int q, a, b;init();while (m--) { scanf("%d", &q); if (q == 1) {scanf("%d%d", &a, &b);int pa = find(a);int pb = find(b);if (pa == pb) continue;parent[pa] = pb;num[pb] += num[pa];sum[pb] += sum[pa]; } else if (q == 2) {scanf("%d%d", &a, &b);int pa = find(a);int pb = find(b);if (pa == pb) continue;parent[a] = pb;num[pa]--;num[pb]++;sum[pa] -= a;sum[pb] += a; } else {scanf("%d", &a);int pa = find(a);printf("%d %d\n", num[pa], sum[pa]); }} } return 0;}