【题目链接】
【思路要点】
- LinkCutTree模板题,支持维护动态森林的联通性,通过询问所在子树的根部来实现。
- 时间复杂度\(O(MLogN)\)。
【代码】
#include<bits/stdc++.h> using namespace std; #define MAXN 10005 struct LinkCutTree { struct Node { bool rev; int father, up, child[2]; }; Node a[MAXN]; int size, n; void init(int x) { n = x; for (int i = 1; i <= n; i++) { size++; a[size].father = 0; a[size].up = 0; a[size].child[0] = 0; a[size].child[1] = 0; a[size].rev = false; } } void pushdown(int x) { if (a[x].rev == false) return; swap(a[x].child[0], a[x].child[1]); a[a[x].child[0]].rev ^= true; a[a[x].child[1]].rev ^= true; a[x].rev = false; } bool get(int x) { pushdown(a[x].father); return x == a[a[x].father].child[1]; } void rotate(int x) { int f = a[x].father; pushdown(f); pushdown(x); int g = a[f].father, tmp = get(x); a[x].up = a[f].up; a[f].up = 0; a[f].child[tmp] = a[x].child[tmp ^ 1]; a[a[x].child[tmp ^ 1]].father = f; a[x].child[tmp ^ 1] = f; a[f].father = x; a[x].father = g; if (g) a[g].child[a[g].child[1] == f] = x; } void splay(int x) { pushdown(x); for (int f = a[x].father; (f = a[x].father); rotate(x)) if (a[f].father) rotate((get(f) == get(x)) ? f : x); } void access(int x) { splay(x); a[a[x].child[1]].up = x; a[a[x].child[1]].father = 0; a[x].child[1] = 0; while (a[x].up) { int tmp = a[x].up; splay(tmp); a[a[tmp].child[1]].up = tmp; a[a[tmp].child[1]].father = 0; a[tmp].child[1] = x; a[x].father = tmp; a[x].up = 0; splay(x); } } void reverse(int x) { access(x); splay(x); a[x].rev ^= true; } void link(int x, int y) { access(x); splay(x); reverse(y); a[x].child[1] = y; a[y].father = x; } void cut(int x, int y) { reverse(x); access(y); splay(x); a[x].child[1] = 0; a[y].father = 0; } int root(int x) { access(x); splay(x); int now = x; pushdown(x); while (a[now].child[0]) { now = a[now].child[0]; pushdown(now); } return now; } }; LinkCutTree T; int main() { int n, m; scanf("%d%d", &n, &m); T.init(n); for (int i = 1; i <= m; i++) { char opt[10]; int x, y; scanf("%s%d%d", opt, &x, &y); if (opt[0] == 'C') T.link(x, y); if (opt[0] == 'D') T.cut(x, y); if (opt[0] == 'Q') { if (T.root(x) == T.root(y)) printf("Yes\n"); else printf("No\n"); } } return 0; }