bzoj2049: [Sdoi2008]Cave 洞穴勘测

【题意】

  给你一个森林,要求支持动态加边删边,并会询问在某一个时刻两点是否联通。

【题解】

  裸的lct,模版题。第一次写对lct,没写过真的难写。。。。

【代码】

  1 #include <iostream>
  2 #include <algorithm>
  3 #include <cstdio>
  4 using namespace std;
  5 const int N=10005;
  6 int n,Q,x,y;
  7 int c[N][2],fa[N],rev[N],a[N];
  8 bool isroot(int x)
  9 {
 10     return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
 11 }
 12 void down(int x)
 13 {
 14     if (rev[x])
 15     {
 16         rev[x]=0;
 17         rev[c[x][0]]^=1;
 18         rev[c[x][1]]^=1;
 19         swap(c[x][0],c[x][1]);
 20     }
 21 }
 22 void rotate(int x)
 23 {
 24     int y=fa[x],z=fa[y],l,r;
 25     if (c[y][0]==x)    l=0;else l=1;r=1^l;
 26     if (!isroot(y))    if (c[z][0]==y)    c[z][0]=x;else c[z][1]=x;
 27     fa[x]=z;
 28     c[y][l]=c[x][r];fa[c[x][r]]=y;
 29     c[x][r]=y;fa[y]=x;
 30 }
 31 void splay(int x)
 32 {
 33     int y=x,z,cnt=0;
 34     while (!isroot(y))
 35     {
 36         a[++cnt]=y;
 37         y=fa[y];
 38     }
 39     a[++cnt]=y;
 40     while (cnt--)    down(a[cnt+1]);
 41     while (!isroot(x))
 42     {
 43         y=fa[x];z=fa[y];
 44         if (!isroot(y))
 45             if (c[y][0]==x ^ c[z][0]==y)
 46                 rotate(x);
 47             else rotate(y);
 48         rotate(x);
 49     }
 50 }
 51 void access(int x)
 52 {
 53     int t=0;
 54     while (x)
 55     {
 56         splay(x);
 57         c[x][1]=t;
 58         t=x;x=fa[x];
 59     }
 60 }
 61 void mt(int x)
 62 {
 63     access(x);
 64     splay(x);
 65 }
 66 void make_root(int x)
 67 {
 68     mt(x);
 69     rev[x]^=1;
 70     down(x);
 71 }
 72 void link(int x,int y)
 73 {
 74     make_root(x);
 75     fa[x]=y;
 76 }
 77 void cut(int x,int y)
 78 {
 79     make_root(x);
 80     mt(y);
 81     fa[x]=c[y][0]=0;
 82 }
 83 bool solve(int x,int y)
 84 {
 85     make_root(x);    
 86     access(y);        
 87     splay(x);    
 88     int z=y;
 89     while (!isroot(y) && y!=fa[y])    y=fa[y];
 90     splay(z);
 91     if (x==y)    return 1;
 92     else return 0;
 93 }
 94 int main()
 95 {
 96     scanf("%d%d",&n,&Q);
 97     char str[10];
 98     while (Q--)
 99     {
100         scanf("%s%d%d",str,&x,&y);
101         if (str[0]=='C')    link(x,y);
102         else    if (str[0]=='D')    cut(x,y);
103         else    if (solve(x,y))    puts("Yes");else puts("No");
104     }
105     return 0;
106 }
View Code

 

posted @ 2017-09-19 21:06 Bleacher 阅读(...) 评论(...) 编辑 收藏