bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门相关的知识,希望对你有一定的参考价值。

link cut tree入门题

首先说明本人只会写自底向上的数组版(都说了不写指针、不写自顶向下QAQ……)

突然发现link cut tree不难写。。。

说一下各个函数作用:

bool isroot(int x):判断x是否为所在重链(splay)的根

void down(int x):下放各种标记

void rotate(int x):在x所在重链(splay)中将x旋转到fa[x]的位置上

void splay(int x):在x坐在重链(splay)中将x旋转到根

void access(int x):把x到x所在树的根变为一条重链,根为链顶,x为链底

void reverse(int x):把x变为所在树的根(先access再打上reverse标记)

void link(int x,int y)连接x,y两点

void cut(int x,int y)断开x,y两点

int find(int x)找到x所在树的根

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char ch=getchar();
 29     while(ch<0||ch>9){if(ch==-)f=1;ch=getchar();}
 30     while(ch>=0&&ch<=9)ret*=10,ret+=ch-0,ch=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int fa[10010],ch[10010][2],rev[10010];
 34 bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
 35 void down(int x)
 36 {
 37     if(!rev[x])return ;
 38     swap(ch[x][0],ch[x][1]);
 39     rev[ch[x][0]]^=1;
 40     rev[ch[x][1]]^=1;
 41     rev[x]=0;
 42 }
 43 void rotate(int x)
 44 {
 45     int y=fa[x],z=fa[y];
 46     if(!isroot(y))
 47         if(ch[z][0]==y)ch[z][0]=x;
 48         else ch[z][1]=x;else ;
 49     fa[x]=z,fa[y]=x;
 50     int d=ch[y][1]==x;
 51     fa[ch[x][d^1]]=y;
 52     ch[y][d]=ch[x][d^1];
 53     ch[x][d^1]=y;
 54 }
 55 int sta[10010],top;
 56 void splay(int x)
 57 {
 58     top=0;sta[++top]=x;
 59     for(int i=x;!isroot(i);i=fa[i])sta[++top]=fa[i];
 60     while(top)down(sta[top--]);
 61     while(!isroot(x))
 62     {
 63         int y=fa[x],z=fa[y];
 64         if(!isroot(y))
 65             if((ch[y][1]==x)^(ch[z][1]==y))rotate(x);
 66             else rotate(y);else 
 67         rotate(x);
 68     }
 69 }
 70 void access(int x)
 71 {
 72     int temp=0;
 73     while(x)
 74     {
 75         splay(x);
 76         ch[x][1]=temp;
 77         temp=x,x=fa[x];
 78     }
 79 }
 80 void reverse(int x)
 81 {
 82     access(x);splay(x),rev[x]^=1;
 83 }
 84 void link(int x,int y)
 85 {
 86     reverse(x);fa[x]=y,splay(x);
 87 }
 88 void cut(int x,int y)
 89 {
 90     reverse(x);access(y);splay(y);ch[y][0]=fa[x]=0;
 91 }
 92 int find(int x)
 93 {
 94     access(x),splay(x);
 95     int y=x;
 96     while(ch[y][0])y=ch[y][0];
 97     return y;
 98 }
 99 int n,m;
100 int main()
101 {
102     char s[11];
103     inin(n),inin(m);
104     re(i,1,m)
105     {
106         strin(s);
107         int x,y;inin(x),inin(y);
108         if(s[0]==C)link(x,y);
109         else if(s[0]==D)cut(x,y);
110         else 
111         {
112             if(find(x)==find(y))printf("Yes\n");
113             else printf("No\n");
114         }
115     }
116      return 0;
117 }

 

以上是关于bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 2049: [Sdoi2008]Cave 洞穴勘測 LCT

BZOJ2049: [Sdoi2008]Cave 洞穴勘测 LCT模板

●BZOJ 2049 [Sdoi2008]Cave洞穴勘测

bzoj 2049: [Sdoi2008]Cave 洞穴勘测

[bzoj2049][Sdoi2008]Cave 洞穴勘测_LCT

BZOJ:2049: [Sdoi2008]Cave 洞穴勘测