题目链接: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