1. 程式人生 > >[SDOI 2008] 洞穴勘測

[SDOI 2008] 洞穴勘測

[題目連結]

         https://www.lydsy.com/JudgeOnline/problem.php?id=2049

[演算法]

          LCT動態維護森林連通性

          時間複雜度 : O(NlogN ^ 2)

[程式碼]

        

#include<bits/stdc++.h>
using namespace std;
#define MAXN 300010 int n , m; struct Link_Cut_Tree { struct Node { int father , son[2]; bool rev; } a[MAXN]; inline void pushdown(int x) { if (a[x].rev) { swap(a[x].son[0] , a[x].son[1]); a[a[x].son[0]].rev ^= 1; a[a[x].son[
1]].rev ^= 1; a[x].rev = false; } } inline bool get(int x) { pushdown(a[x].father); return a[a[x].father].son[1] == x; } inline bool nroot(int x) { return a[a[x].father].son[0] == x | a[a[x].father].son[1] == x; } inline void
rotate(int x) { int f = a[x].father , g = a[f].father; int tmpx = get(x) , tmpf = get(f); int w = a[x].son[tmpx ^ 1]; if (nroot(f)) a[g].son[tmpf] = x; a[x].son[tmpx ^ 1] = f; a[f].son[tmpx] = w; if (w) a[w].father = f; a[f].father = x; a[x].father = g; } inline void splay(int x) { int y = x , z = 0; static int st[MAXN]; st[++z] = y; while (nroot(y)) st[++z] = y = a[y].father; while (z) pushdown(st[z--]); while (nroot(x)) { int y = a[x].father , z = a[y].father; if (nroot(y)) rotate((a[y].son[0] == x) ^ (a[z].son[0] == y) ? (y) : (x)); rotate(x); } } inline void access(int x) { for (int y = 0; x; x = a[y = x].father) { splay(x); a[x].son[1] = y; } } inline void make_root(int x) { access(x); splay(x); a[x].rev ^= 1; } inline void cut(int x , int y) { make_root(x); if (find_root(y) == x && a[x].father == y && !a[x].son[1]) a[x].father = a[y].son[0] = 0; } inline void link(int x , int y) { make_root(x); if (find_root(y) != x) a[x].father = y; } inline int find_root(int x) { access(x); splay(x); while (a[x].son[0]) { pushdown(x); x = a[x].son[0]; } return x; } } LCT; int main() { scanf("%d%d" , &n , &m); for (int i = 1; i <= m; i++) { char type[10]; scanf("%s" , &type); if (type[0] == 'C') { int x , y; scanf("%d%d" , &x , &y); LCT.link(x , y); } else if (type[0] == 'D') { int x , y; scanf("%d%d" , &x , &y); LCT.cut(x , y); } else { int x , y; scanf("%d%d" , &x , &y); if (LCT.find_root(x) == LCT.find_root(y)) printf("Yes\n"); else printf("No\n"); } } return 0; }