bzoj 2049 洞穴勘测

题目大意:

一些点 支持插入边 删除边 保证图始终无环

询问两个点是否联通

思路:

LCT裸题

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2139062143
10 #define ll long long
11 #define MAXN 100100
12 using namespace std;
13 inline int read()
14 {
15     int x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 int n,m;
21 int rt,Size;
22 struct LCT
23 {
24     int ch[MAXN][2],f[MAXN],tag[MAXN],st[MAXN];
25     inline int isroot(int x){return ch[f[x]][0]!=x && ch[f[x]][1]!=x;}
26     inline int which(int x) {return ch[f[x]][1]==x;}
27     inline void rotate(int x)
28     {
29         int fa=f[x],ff=f[fa],k=which(x);
30         if(!isroot(fa)) ch[ff][ch[ff][1]==fa]=x;f[x]=ff;
31         ch[fa][k]=ch[x][k^1],f[ch[fa][k]]=fa,ch[x][k^1]=fa,f[fa]=x;
32     }
33     inline void pshd(int pos)
34     {
35         if(tag[pos]&&pos)
36         {
37             tag[pos]=0,tag[ch[pos][1]]^=1,tag[ch[pos][0]]^=1;
38             swap(ch[pos][0],ch[pos][1]);
39         }
40     }
41     void splay(int x)
42     {
43         int top=0;st[++top]=x;
44         for(int i=x;!isroot(i);i=f[i])st[++top]=f[i];
45         for(int i=top;i;i--) pshd(st[i]);
46         for(int fa;!isroot(x);rotate(x))
47             if(!isroot(fa=f[x])) rotate(which(x)==which(fa)?fa:x);
48     }
49     inline void access(int x)
50     {
51         int t=0;
52         for(;x;t=x,x=f[x]) {splay(x);ch[x][1]=t;}
53     }
54     inline void reverse(int x) {access(x);splay(x);tag[x]^=1;}
55     inline void link(int x,int y) {reverse(x);f[x]=y;splay(x);}
56     inline void cut(int x,int y) {reverse(x);access(y);splay(y);ch[y][0]=f[x]=0;}
57     inline int find(int x)
58     {
59         access(x);splay(x);
60         while(ch[x][0]) x=ch[x][0];
61         return x;
62     }
63 }tr;
64 int main()
65 {
66     char ch[10];
67     int x,y;
68     n=read(),m=read();
69     for(int i=1;i<=m;i++)
70     {
71         scanf("%s",ch);
72         x=read();y=read();
73         if(ch[0]=='C') tr.link(x,y);
74         else if(ch[0]=='D') tr.cut(x,y);
75         else
76         {
77             if(tr.find(x)==tr.find(y)) printf("Yes\n");
78             else printf("No\n");
79         }
80     }
81 }
View Code

 

posted @ 2018-02-07 13:24  jack_yyc  阅读(114)  评论(0编辑  收藏  举报