bzoj 2049 洞穴勘测
题目大意:
一些点 支持插入边 删除边 保证图始终无环
询问两个点是否联通
思路:
LCT裸题
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #define inf 2139062143 10 #define ll long long 11 #define MAXN 100100 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 17 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 int n,m; 21 int rt,Size; 22 struct LCT 23 { 24 int ch[MAXN][2],f[MAXN],tag[MAXN],st[MAXN]; 25 inline int isroot(int x){return ch[f[x]][0]!=x && ch[f[x]][1]!=x;} 26 inline int which(int x) {return ch[f[x]][1]==x;} 27 inline void rotate(int x) 28 { 29 int fa=f[x],ff=f[fa],k=which(x); 30 if(!isroot(fa)) ch[ff][ch[ff][1]==fa]=x;f[x]=ff; 31 ch[fa][k]=ch[x][k^1],f[ch[fa][k]]=fa,ch[x][k^1]=fa,f[fa]=x; 32 } 33 inline void pshd(int pos) 34 { 35 if(tag[pos]&&pos) 36 { 37 tag[pos]=0,tag[ch[pos][1]]^=1,tag[ch[pos][0]]^=1; 38 swap(ch[pos][0],ch[pos][1]); 39 } 40 } 41 void splay(int x) 42 { 43 int top=0;st[++top]=x; 44 for(int i=x;!isroot(i);i=f[i])st[++top]=f[i]; 45 for(int i=top;i;i--) pshd(st[i]); 46 for(int fa;!isroot(x);rotate(x)) 47 if(!isroot(fa=f[x])) rotate(which(x)==which(fa)?fa:x); 48 } 49 inline void access(int x) 50 { 51 int t=0; 52 for(;x;t=x,x=f[x]) {splay(x);ch[x][1]=t;} 53 } 54 inline void reverse(int x) {access(x);splay(x);tag[x]^=1;} 55 inline void link(int x,int y) {reverse(x);f[x]=y;splay(x);} 56 inline void cut(int x,int y) {reverse(x);access(y);splay(y);ch[y][0]=f[x]=0;} 57 inline int find(int x) 58 { 59 access(x);splay(x); 60 while(ch[x][0]) x=ch[x][0]; 61 return x; 62 } 63 }tr; 64 int main() 65 { 66 char ch[10]; 67 int x,y; 68 n=read(),m=read(); 69 for(int i=1;i<=m;i++) 70 { 71 scanf("%s",ch); 72 x=read();y=read(); 73 if(ch[0]=='C') tr.link(x,y); 74 else if(ch[0]=='D') tr.cut(x,y); 75 else 76 { 77 if(tr.find(x)==tr.find(y)) printf("Yes\n"); 78 else printf("No\n"); 79 } 80 } 81 }