比较简单的LCT,就一个link,Cut操作(就是HDU那道题中的两个),直接上代码:
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <vector>
#define LL long long
#define INF 0x3fffffff
#define FOR(i,x,y) for(int i = x;i < y;i ++)
#define IFOR(i,x,y) for(int i = x;i > y;i --)
#define MAXN 11000
using namespace std;
int n,q;
struct LCT{
int pre[MAXN],ch[MAXN][2];
int flip[MAXN];
bool rt[MAXN];
void Update_Flip(int x){
if(!x) return;
swap(ch[x][0],ch[x][1]);
flip[x] ^= 1;
}
void Init(){
memset(ch,0,sizeof(ch));
memset(flip,0,sizeof(flip));
memset(pre,0,sizeof(pre));
memset(rt,true,sizeof(rt));
}
void PushUp(int x){
}
void PushDown(int x){
if(flip[x]){
if(ch[x][0]) Update_Flip(ch[x][0]);
if(ch[x][1]) Update_Flip(ch[x][1]);
flip[x] = 0;
}
}
void Rotate(int x,int kind){
int y = pre[x];
PushDown(y);
PushDown(x);
ch[y][!kind] = ch[x][kind];
if(ch[x][kind]) pre[ch[x][kind]] = y;
if(rt[y]){
rt[x] = true;
rt[y] = false;
}
else{
if(ch[pre[y]][1] == y) ch[pre[y]][1] = x;
if(ch[pre[y]][0] == y) ch[pre[y]][0] = x;
}
pre[x] = pre[y];
pre[y] = x;
ch[x][kind] = y;
PushUp(y);
}
void Splay(int x){
PushDown(x);
while(!rt[x]){
int y = pre[x];
int z = pre[y];
PushDown(z); PushDown(y); PushDown(x);
if(rt[y]){
Rotate(x,ch[y][0] == x);
}
else{
int kind = ch[z][0] == y;
if(ch[y][kind] == x){
Rotate(x,!kind);
Rotate(x,kind);
}
else{
Rotate(y,kind);
Rotate(x,kind);
}
}
}
PushUp(x);
}
void Access(int x){
int fa = 0;
for(;x;x = pre[fa = x]){
Splay(x);
rt[ch[x][1]] = true;
rt[ch[x][1] = fa] = false;
PushUp(x);
}
}
int GetRoot(int x){
Access(x);
Splay(x);
while(ch[x][0]) x = ch[x][0];
return x;
}
void MakeRoot(int x){
Access(x);
Splay(x);
Update_Flip(x);
}
bool Link(int u,int v){
if(GetRoot(u) == GetRoot(v)) return false;
MakeRoot(u);
pre[u] = v;
Access(u);
return true;
}
bool Cut(int u,int v){
if(u == v || GetRoot(u) != GetRoot(v)) return false;
MakeRoot(u);
Access(v);
Splay(v);
if(ch[v][0]) pre[ch[v][0]] = pre[v],rt[ch[v][0]] = true;
pre[v] = 0;
ch[v][0] = 0;
PushUp(v);
return true;
}
bool Query(int u,int v){
if(GetRoot(u) == GetRoot(v)) return true;
return false;
}
}lct;
int main(){
//freopen("test.in","r",stdin);
while(~scanf("%d%d",&n,&q)){
lct.Init();
char op[10];
int u,v;
FOR(i,0,q){
scanf("%s%d%d",op,&u,&v);
if(!strcmp(op,"Connect")){
lct.Link(u,v);
}
else if(!strcmp(op,"Destroy")){
lct.Cut(u,v);
}
else{
if(lct.Query(u,v)){
printf("Yes\n");
}
else
printf("No\n");
}
}
}
return 0;
}