bzoj2049[Sdoi2008]-Cave洞穴勘测
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2049
题目大意:有n个洞 m个操作
操作有三种:
Connect u v 联通u到v
Destroy u v 断开u到v
Query u v 询问u和v是否连通
题解:LCT的模版题*1
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 10100 struct LinkCutTree { int fa[maxn]; int son[maxn][2]; int rev[maxn]; void clear(int n) { for (int i=0;i<=n;i++) {rev[i]=son[i][0]=son[i][1]=fa[i]=0;} } bool Is_root(int x) { if (son[fa[x]][0]==x) return false; if (son[fa[x]][1]==x) return false; return true; } void Push_Down(int x) { if (rev[x]) { int t=son[x][0]; son[x][0]=son[x][1]; son[x][1]=t; rev[son[x][0]]^=1; rev[son[x][1]]^=1; rev[x]=0; } } void Rotate(int x) { int y=fa[x],z=fa[y]; int a=son[y][1]==x; int b=son[z][1]==y; if (!Is_root(y)) son[z][b]=x; if (son[x][1-a]!=0) fa[son[x][1-a]]=y; son[y][a]=son[x][1-a]; son[x][1-a]=y; fa[y]=x;fa[x]=z; } int sta[maxn]; void Pre(int x) { int tp=0; for (;!Is_root(x);x=fa[x]) sta[++tp]=x; sta[++tp]=x; while (tp>0) {Push_Down(sta[tp]);tp--;} } void Splay(int x) { Pre(x); while (!Is_root(x)) { int y=fa[x],z=fa[y]; if (!Is_root(y)) { int a=son[y][1]==x; int b=son[z][1]==y; if (a==b) Rotate(y); else Rotate(x); }Rotate(x); } } void Access(int x) { int last=0; while (x!=0) { Splay(x); son[x][1]=last; last=x; x=fa[x]; } } void Make_root(int x) { Access(x); Splay(x); rev[x]^=1; } void Split(int x,int y) { Make_root(x); Access(y); Splay(y); } int Find_root(int x) { Access(x); Splay(x); while (son[x][0]!=0) x=son[x][0]; return x; } bool Connect(int x,int y) { if (Find_root(x)==Find_root(y)) return true; return false; } void Link(int x,int y) { if (Connect(x,y)) return; Make_root(x); fa[x]=y; } void Cut(int x,int y) { if (!Connect(x,y)) return; Split(x,y); if (son[y][0]!=x) return; fa[x]=0; son[y][0]=0; } }lct; int main() { //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); int n,m,i,u,v;char c[20]; while (scanf("%d%d",&n,&m)!=EOF) { lct.clear(n); for (i=1;i<=m;i++) { scanf("\n"); scanf("%s%d%d",c,&u,&v); if (c[0]=='C') lct.Link(u,v); else if (c[0]=='D') lct.Cut(u,v); else if (c[0]=='Q') { if (lct.Connect(u,v)) printf("Yes\n"); else printf("No\n"); } } } return 0; }我会说这个模版我打了三次没有一次一A吗QAQ