LinkCutTree试水之bzoj2049[Sdoi08]山洞勘测题解
LinkCutTree试水之bzoj2049[Sdoi08]洞穴勘测题解
题目大意
一张无向图,初始时没有边,写一个程序支持动态添边、删边、查询两点是否连通。题解
用LCT维护图的连通性。看来指针还是比较慢的。Code
#include <cstdio>
#include <algorithm>
#define maxn 10005
using namespace std;
int n, m;
struct node
{
bool rev;
node *fa, *lc, *rc;
node() { rev = false; fa = lc = rc = NULL; }
node(bool xrev, node *xfa, node *xlc, node *xrc)
{
rev = xrev;
fa = xfa; lc = xlc; rc = xrc;
}
void pushdown();
}*nil = new node(), *T[maxn];
void node :: pushdown()
{
if(this == fa -> lc || this == fa -> rc)
{
fa -> pushdown();
}
if(rev)
{
if(lc != nil) lc -> rev ^= 1;
if(rc != nil) rc -> rev ^= 1;
swap(lc, rc);
rev = false;
}
}
void zag(node *x)
{
node *y = x -> fa;
y -> rc = x -> lc;
x -> lc -> fa = y;
x -> lc = y;
x -> fa = y -> fa;
if(y == y -> fa -> lc) y -> fa -> lc = x;
else if(y == y -> fa -> rc) y -> fa -> rc = x;
y -> fa = x;
}
void zig(node *x)
{
node *y = x -> fa;
y -> lc = x -> rc;
x -> rc -> fa = y;
x -> rc = y;
x -> fa = y -> fa;
if(y == y -> fa -> lc) y -> fa -> lc = x;
else if(y == y -> fa -> rc) y -> fa -> rc = x;
y -> fa = x;
}
void splay(node *x)
{
node *y = nil, *z = nil;
x -> pushdown();
while(x == x -> fa -> lc || x == x -> fa -> rc)
{
y = x -> fa; z = y -> fa;
if(x == y -> lc)
{
if(y == z -> lc) zig(y);
zig(x);
}
else
{
if(y == z -> rc) zag(y);
zag(x);
}
}
}
inline void access(node *x)
{
for(node *y = nil; x != nil; x = x -> fa)
{
splay(x);
x -> rc = y;
y = x;
}
}
inline void makeroot(node *x)
{
access(x); splay(x); x -> rev ^= 1;
}
inline void lnk(node *x, node *y)
{
makeroot(x);
x -> fa = y;
}
inline void cut(node *x, node *y)
{
makeroot(x);
access(y); splay(y);
x -> fa = y -> lc = nil;
}
inline node *find(node *x)
{
access(x);
splay(x);
while(x -> lc != nil) x = x -> lc;
return x;
}
inline void read(int &a)
{
char ch = getchar(); a = 0;
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9')
{
a = a * 10 + ch - 48;
ch = getchar();
}
}
int main()
{
char opt[10];
int a, b;
read(n); read(m);
*nil = node(false, nil, nil, nil);
for(int i = 1; i <= n; ++i) T[i] = new node(false, nil, nil, nil);
while(m--)
{
scanf("%s", opt);
read(a); read(b);
switch(opt[0])
{
case 'C': lnk(T[a], T[b]);
break;
case 'D': cut(T[a], T[b]);
break;
case 'Q': if(find(T[a]) == find(T[b])) puts("Yes");
else puts("No");
break;
default : break;
}
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。