bzoj2049: [Sdoi2008]Cave 洞穴勘测
这道题是裸的lct(link-cut-tree) 觉得自己讲的不是很好 推荐个博客吧
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=10007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int n,m; int c[M][2],fa[M],rev[M]; bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;} void revs(int x){ if(!x) return ; rev[x]^=1; swap(c[x][0],c[x][1]); } void down(int x){ if(!rev[x]) return ; rev[x]=0; revs(c[x][0]); revs(c[x][1]); } void rotate(int x){ int y=fa[x],z=fa[y],l=0,r=1; if(c[y][1]==x) l=1,r=0; if(!isrt(y)){ if(c[z][0]==y) c[z][0]=x; else c[z][1]=x; } fa[x]=z; fa[y]=x; fa[c[x][r]]=y; c[y][l]=c[x][r]; c[x][r]=y; } int st[M],top; void splay(int x){ if(!x) return ; st[++top]=x;for(int i=x;!isrt(i);i=fa[i]) st[++top]=fa[i]; while(top) down(st[top--]); while(!isrt(x)){ int y=fa[x],z=fa[y]; if(!isrt(y)){ if(c[z][0]==y^c[y][0]==x) rotate(x); else rotate(y); } rotate(x); } } void acs(int x){ int y=x,t=0; while(x){ splay(x); c[x][1]=t; t=x; x=fa[x]; } splay(y); } void mrt(int x){acs(x); revs(x);} void link(int x,int y){mrt(x); fa[x]=y;} void cut(int x,int y){mrt(x); acs(y); c[y][0]=fa[x]=0;} int find(int x){ while(c[x][0]) down(x),x=c[x][0]; splay(x); return x; } void push_ans(int x,int y){ mrt(x); acs(y); if(find(y)==x) printf("Yes\n"); else printf("No\n"); } int main() { char ch[15]; int x,y; n=read(); m=read(); for(int i=1;i<=m;i++){ scanf("%s",ch); x=read(); y=read(); if(ch[0]=='C') link(x,y); else if(ch[0]=='D') cut(x,y); else push_ans(x,y); // for(int i=1;i<=n;++i)printf("%d %d(%d,%d) %d\n",i,fa[i],c[i][0],c[i][1],rev[i]); } return 0; }