codevs洞穴勘测原题戳这里
题目大意:
建路 Connect u v
毁路 Destroy u v
查询路是否联通 Query u v
用到的几个基本操作,link,cut,access,reverse,find
/*本题中所用到的ch和fa,为splay树上的,与原树没有关系*/
/*博主个人爱好结构体,不适者可自动yy成数组*/
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int n,m;
int st[10050];
struct LCT{
int ch[2];
int fa,rev;
}t[10050];
int isroot(int x)
{
return t[t[x].fa].ch[0]!=x&&t[t[x].fa].ch[1]!=x;
}
void pushdown(int k)
{
int l=t[k].ch[0],r=t[k].ch[1];
if(t[k].rev)
{
t[k].rev^=1;
t[l].rev^=1;
t[r].rev^=1;
swap(t[k].ch[0],t[k].ch[1]);
}
}
void rotate(int x)
{
int y=t[x].fa,z=t[y].fa,l,r;
if(t[y].ch[0]==x)l=0;
else l=1;
r=l^1;
if(!isroot(y))//如果y不是splay树的树根
{
if(t[z].ch[0]==y)t[z].ch[0]=x;
else t[z].ch[1]=x;
}
t[x].fa=z;
t[y].fa=x;
t[t[x].ch[r]].fa=y;
t[y].ch[l]=t[x].ch[r];
t[x].ch[r]=y;
}
//一些被注释掉的部分为正常的splay,博主手残试了下,不适用于本题,会全T
//bool son(int x)
//{
// return t[t[x].fa].ch[1]==x;//rc:1,lc:0
//}
//
//void point(int x,int fa,bool z)
//{
// if(x)t[x].fa=fa;
// if(fa)t[fa].ch[z]=x;
// //else root=x;
//}
//
//void rotate(int x)
//{
// int y=t[x].fa;
// int z=t[y].fa;
// bool yy=son(y),xx=son(x);
// point(t[x].ch[!xx],y,xx);
// point(y,x,!xx);
// point(x,z,yy);
rejs(y);
rejs(x);
//}
void splay(int x)
{
int top=0;
st[++top]=x;
for(int i=x;!isroot(i);i=t[i].fa)
{
st[++top]=t[i].fa;
}
for(int i=top;i;i--)pushdown(st[i]);
while(!isroot(x))
{
int y=t[x].fa,z=t[y].fa;
if(!isroot(y))
{
if(t[y].ch[0]==x^t[z].ch[0]==y)rotate(x);//优先级!!!!!!!
else
rotate(y);
}
rotate(x);
}
}
void access(int x)
{
int l=0;
while(x)
{
splay(x);
t[x].ch[1]=l;
l=x;
x=t[x].fa;
}
}
void rever(int x)
{
access(x);
splay(x);
t[x].rev^=1;
}
void link(int x,int y)
{
rever(x);
t[x].fa=y;
splay(x);
}
void cut(int x,int y)
{
rever(x);
access(y);
splay(y);
t[y].ch[0]=t[x].fa=0;
}
int find(int x)
{
access(x);
splay(x);
int y=x;
while(t[y].ch[0])y=t[y].ch[0];
return y;
}
int main()
{
char ch[10];
int x,y;
// scanf("%d%d",&n,&m);
n=read(),m=read();
for(int i=1;i<=m;i++)
{
scanf("%s",ch);
// scanf("%d%d",&x,&y);
x=read(),y=read();
if(ch[0]=='C')link(x,y);
else if(ch[0]=='D')cut(x,y);
else
{
if(find(x)==find(y))printf("Yes\n");
else printf("No\n");
}
}
return 0;
}