【SDOI2008】【link-cut tree】洞穴勘测
2013-04-14 10:37
344 查看
题目大意:维护一个森林中两点的连通性情况,有插入一条边和删除一条边两种操作。
直接使用link-cut-tree维护森林的连通性即可。
注意在找出一条路径后需要维护splay上的翻转标记。
还有就是splay旋转的时候不能写把两种情况合在一句写,这样有可能引起死循环!这个Bug我找了很久。以后一定要注意,见注释的那句话。
代码:
直接使用link-cut-tree维护森林的连通性即可。
注意在找出一条路径后需要维护splay上的翻转标记。
还有就是splay旋转的时候不能写把两种情况合在一句写,这样有可能引起死循环!这个Bug我找了很久。以后一定要注意,见注释的那句话。
代码:
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int maxn = 10000 + 10; int ch[maxn][2],pre[maxn]; bool rev[maxn]; int n,m; void init() { freopen("bzoj2049.in","r",stdin); freopen("bzoj2049.out","w",stdout); } void update(int x) { if(rev[x]) { swap(ch[x][0],ch[x][1]); rev[ ch[x][0] ] = !rev[ ch[x][0] ]; rev[ ch[x][1] ] = !rev[ ch[x][1] ]; rev[x] = false; } } void rotate(int x,int f) { int y = pre[x],z = pre[y]; ch[y][!f] = ch[x][f]; pre[x] = pre[y]; // if(pre[x])ch[ pre[y] ][ pre[y][1] == y ] = x; if(ch[z][0] == y)ch[z][0] = x; else if(ch[z][1] == y)ch[z][1] = x; pre[ ch[x][f] ] = y; pre[y] = x; ch[x][f] = y; update(y); } bool isroot(int x) { return ch[pre[x]][0] != x && ch[pre[x]][1] != x; } void push_down(int x) { if(!isroot(x))push_down(pre[x]); update(x); } void splay(int x) { push_down(x); while(!isroot(x)) { if(isroot(pre[x]))rotate(x,ch[pre[x]][0] == x); else { int y = pre[x],z = pre[y]; int f = (ch[z][0] == y); if(ch[y][f] == x)rotate(x,!f),rotate(x,f); else rotate(y,f),rotate(x,f); } } update(x); } void access(int u) { for(int v = 0;u;v = u,u = pre[u]) { splay(u); ch[u][1] = v; update(u); } } void cut(int x,int y) { access(y); splay(x); if(pre[x] == y)pre[x] = 0; else { access(x); splay(y); pre[y] = 0; } } void evert(int x) { access(x); splay(x); rev[x] = !rev[x]; } void link(int a,int b) { evert(a); pre[a] = b; } bool query(int a,int b) { int x = a,y = b; access(y); for(y = 0;x;x = pre[x]) { splay(x); if(!pre[x])break; y = x; } for(;ch[x][1];x = ch[x][1]); return x == b; } void readdata() { memset(rev,false,sizeof(rev)); memset(pre,0,sizeof(pre)); scanf("%d%d",&n,&m); for(int i = 1;i <= m;i++) { int a,b; char op[10]; scanf("%s%d%d",op,&a,&b); if(op[0] == 'Q')puts(query(a,b) ? "Yes" : "No"); if(op[0] == 'C')link(a,b); if(op[0] == 'D')cut(a,b); } } int main() { init(); readdata(); return 0; }
相关文章推荐
- bzoj2049 [Sdoi2008]Cave 洞穴勘测 (Link Cut Tree)
- BZOJ 2049 [Sdoi2008]Cave 洞穴勘测 ——Link-Cut Tree
- cogs1889 [SDOI2008]Cave 洞穴勘测 link-cut tree
- bzoj 2049 SDOI 2008 Cave 洞穴勘测 [Link-Cut Tree]
- 【BZOJ2049】[Sdoi2008]Cave 洞穴勘测【Link-Cut Tree】
- BZOJ 题目2049: [Sdoi2008]Cave 洞穴勘测(link cut tree)
- BZOJ2049: [Sdoi2008]Cave 洞穴勘测 Link-cut-tree
- 【bzoj2049】[Sdoi2008]Cave 洞穴勘测 link-cut-tree
- BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 link cut tree
- bzoj 2049: [Sdoi2008]Cave 洞穴勘测 link cut tree
- bzoj 2049: [Sdoi2008]Cave 洞穴勘测 (link-cut-tree)
- [bzoj2049][Sdoi2008]Cave 洞穴勘测 Link-Cut-Tree
- BZOJ 2049 Sdoi2008 Cave 洞穴勘测 动态树 Link-Cut-Tree
- 【BZOJ2049】[Sdoi2008]Cave 洞穴勘测 Link-Cut-Tree
- BZOJ2049: [Sdoi2008]Cave 洞穴勘测 Link-Cut-Tree 模板题
- 【BZOJ2049】【SDOI2008】洞穴勘测(LCT)
- BZOJ 2049 [Sdoi2008]Cave 洞穴勘测(动态树)
- [BZOJ2049]洞穴勘测[BZOJ2157]旅游Link-Cut Tree模板题
- bzoj2049: [Sdoi2008]Cave 洞穴勘测 LCT
- BZOJ2049: [Sdoi2008]Cave 洞穴勘测