BZOJ2049: [Sdoi2008]Cave 洞穴勘测
【传送门:BZOJ2049】
简要题意:
给出n个点,有m种操作:
1.Connect x y将x点和y点连通
2.Destroy x y使得x点和y点不连通
3.Query x y询问x和y是否连通
题解:
LCT的模板题,动态树例题
参考代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> using namespace std; struct node { int f,son[2]; bool fz; node() { fz=false; } }tr[110000]; void reverse(int x) { tr[x].fz=false; swap(tr[x].son[0],tr[x].son[1]); int lc=tr[x].son[0],rc=tr[x].son[1]; tr[lc].fz=1-tr[lc].fz; tr[rc].fz=1-tr[rc].fz; } void rotate(int x,int w) { int f=tr[x].f,ff=tr[f].f; int r,R; r=tr[x].son[w],R=f; tr[R].son[1-w]=r; if(r!=0) tr[r].f=R; r=x;R=ff; if(tr[R].son[0]==f) tr[R].son[0]=r; else if(tr[R].son[1]==f) tr[R].son[1]=r; tr[r].f=R; r=f;R=x; tr[R].son[w]=r; tr[r].f=R; } int tmp[11000]; void splay(int x,int rt) { int i=x;int s=0; while(tr[i].f!=0&&(tr[tr[i].f].son[0]==i||tr[tr[i].f].son[1]==i)) { tmp[++s]=i; i=tr[i].f; } tmp[++s]=i; while(s!=0) { i=tmp[s--]; if(tr[i].fz==true) reverse(i); } while(tr[x].f!=0&&(tr[tr[x].f].son[0]==x||tr[tr[x].f].son[1]==x)) { int f=tr[x].f,ff=tr[f].f; if(ff==rt||(tr[ff].son[0]!=f&&tr[ff].son[1]!=f)) { if(tr[f].son[0]==x) rotate(x,1); else if(tr[f].son[1]==x) rotate(x,0); } else { if(tr[f].son[0]==x&&tr[ff].son[0]==f){rotate(f,1);rotate(x,1);continue;} if(tr[f].son[0]==x&&tr[ff].son[1]==f){rotate(x,1);rotate(x,0);continue;} if(tr[f].son[1]==x&&tr[ff].son[0]==f){rotate(x,0);rotate(x,1);continue;} if(tr[f].son[1]==x&&tr[ff].son[1]==f){rotate(f,0);rotate(x,0);continue;} } } } void access(int x) { int y=0; while(x!=0) { splay(x,0); tr[x].son[1]=y; if(y!=0) tr[y].f=x; y=x;x=tr[x].f; } } void makeroot(int x) { access(x);splay(x,0); tr[x].fz=1-tr[x].fz; } void link(int x,int y) { makeroot(x); tr[x].f=y; access(x); } void cut(int x,int y) { makeroot(x); access(y); splay(y,0); tr[tr[y].son[0]].f=0;tr[y].son[0]=0; } int findroot(int x) { access(x); splay(x,0); while(tr[x].son[0]!=0) x=tr[x].son[0]; return x; } char st[11]; int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%s%d%d",st+1,&x,&y); if(st[1]=='Q') if(findroot(x)==findroot(y)) printf("Yes\n");else printf("No\n"); if(st[1]=='C') link(x,y); if(st[1]=='D') cut(x,y); } return 0; }
渺渺时空,茫茫人海,与君相遇,幸甚幸甚