1. 程式人生 > >【BZOJ】2049 [Sdoi2008]Cave 洞穴勘測

【BZOJ】2049 [Sdoi2008]Cave 洞穴勘測

.com oid pre sdoi2008 print reserve mes tdi down

【算法】Link-Cut Tree

【題解】lct

不是很懂你們會壓常數的>_<!

技術分享
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=10010;
int f[maxn],t[maxn][2],n,m;
bool g[maxn];
bool isroot(int x)
{return (t[f[x]][0]!=x&&t[f[x]][1]!=x);}
void pushdown(int x)
{
    if
(g[x]) { swap(t[x][0],t[x][1]); g[t[x][0]]^=1;g[t[x][1]]^=1; g[x]=0; } } void rotate(int x) { int k=x==t[f[x]][1]; int y=f[x]; t[y][k]=t[x][!k];f[t[x][!k]]=y; if(!isroot(y))t[f[y]][y==t[f[y]][1]]=x;f[x]=f[y];f[y]=x; t[x][!k]=y; } int N[maxn]; void splay(int
x) { int tot=0; int y=x;//此處不能直接上移x,因為待會還要用。 while(!isroot(y))N[++tot]=y,y=f[y]; pushdown(y); for(int i=tot;i>=1;i--)pushdown(N[i]); while(!isroot(x)) { if(isroot(f[x])){rotate(x);return;} int X=x==t[f[x]][1],Y=f[x]==t[f[f[x]]][1]; if(X^Y)rotate(x),rotate(x);
else rotate(f[x]),rotate(x); } } void access(int x) { int y=0; while(x) { splay(x); t[x][1]=y; y=x;x=f[x]; } } void reserve(int x) {access(x);splay(x);g[x]^=1;} void link(int x,int y) {reserve(x);f[x]=y;} void cut(int x,int y) {reserve(x);access(y);splay(y);t[y][0]=f[x]=0;} int ask_root(int x) { access(x);splay(x); while(t[x][0])x=t[x][0]; return x; } void find_root(int x,int y) { if(ask_root(x)==ask_root(y))printf("Yes\n");else printf("No\n"); } char s[20]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%s%d%d",s+1,&x,&y); if(s[1]==C)link(x,y); if(s[1]==D)cut(x,y); if(s[1]==Q)find_root(x,y); } return 0; }
View Code

【BZOJ】2049 [Sdoi2008]Cave 洞穴勘測