【題解】Luogu P2147 [SDOI2008]洞穴勘測
阿新 • • 發佈:2018-12-31
原題傳送門
這題用Link-Cut-Tree解決,Link-Cut-Tree詳解
我不太會踩爆Link-Cut-Tree的並查集做法qaq
我們用Link-Cut-Tree維護連通性(十分無腦)
Connect操作:把u,v兩個點連起來
Destroy操作:把u,v兩個點分開來
Query操作:判斷在這個森林裡u的根和v的根是否相等
#include <bits/stdc++.h> #define N 10005 using namespace std; inline int read() { register int f=1,x=0;register char ch; do{ch=getchar();if(ch=='-')f=-1;}while(ch<'0'||ch>'9'); do{x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}while(ch>='0'&&ch<='9'); return f*x; } inline void Swap(register int &a,register int &b) { a^=b^=a^=b; } struct Link_Cut_Tree{ int c[N][2],fa[N],top,q[N],rev[N]; inline void pushdown(register int x){ if(rev[x]) { register int l=c[x][0],r=c[x][1]; rev[l]^=1,rev[r]^=1,rev[x]^=1; Swap(c[x][0],c[x][1]); } } inline bool isroot(register int x) { return c[fa[x]][0]!=x&&c[fa[x]][1]!=x; } inline void rotate(register int x) { int y=fa[x],z=fa[y],l,r; l=c[y][0]==x?0:1; r=l^1; if(!isroot(y)) c[z][c[z][0]==y?0:1]=x; fa[x]=z; fa[y]=x; fa[c[x][r]]=y; c[y][l]=c[x][r]; c[x][r]=y; } inline void splay(register int x) { top=1; q[top]=x; for(register int i=x;!isroot(i);i=fa[i]) q[++top]=fa[i]; for(register int i=top;i;--i) pushdown(q[i]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) rotate((c[y][0]==x)^(c[z][0]==y)?(x):(y)); rotate(x); } } inline void access(register int x) { for(register int t=0;x;t=x,x=fa[x]) { splay(x); c[x][1]=t; } } inline void makeroot(register int x) { access(x); splay(x); rev[x]^=1; } inline int findroot(register int x) { access(x); splay(x); while(c[x][0]) x=c[x][0]; return x; } inline void split(register int x,register int y) { makeroot(x); access(y); splay(y); } inline void cut(register int x,register int y) { split(x,y); c[y][0]=0; fa[x]=0; } inline void link(register int x,register int y) { makeroot(x); fa[x]=y; } }T; int n,m; int main() { n=read(),m=read(); char ch[10]; while(m--) { scanf("%s",ch); if(ch[0]=='C') { int x=read(),y=read(); T.link(x,y); } else if(ch[0]=='D') { int x=read(),y=read(); T.cut(x,y); } else { int x=read(),y=read(); puts(T.findroot(x)==T.findroot(y)?"Yes":"No"); } } return 0; }