博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ 2049] [Sdoi2008] Cave 洞穴勘测 【LCT】
阅读量:5030 次
发布时间:2019-06-12

本文共 2660 字,大约阅读时间需要 8 分钟。

题目链接:

 

题目分析

LCT的基本模型,包括 Link ,Cut 操作和判断两个点是否在同一棵树内。

Link(x, y) : Make_Root(x); Splay(x); Father[x] = y;

Cut(x, y) : Make_Root(x); Access(y); 断掉 y 和 Son[y][0]; 注意修改 Son[y][0] 的 isRoot 和 Father

判断 x, y 是否在同一棵数内,我们就看两个点所在树的根是否相同,使用 Find_Root();

Find_Root(x) : Access(x); Splay(x); while (Son[x][0] != 0) x = Son[x][0]; 然后 x 就是树根了。

 

代码

#include 
#include
#include
#include
#include
#include
using namespace std;inline void Read(int &Num){ char c = getchar(); bool Neg = false; while (c < '0' || c > '9') { if (c == '-') Neg = true; c = getchar(); } Num = c - '0'; c = getchar(); while (c >= '0' && c <= '9') { Num = Num * 10 + c - '0'; c = getchar(); } if (Neg) Num = -Num;}const int MaxN = 10000 + 5;int n, m;int Father[MaxN], Son[MaxN][2];bool isRoot[MaxN], Rev[MaxN];inline void Reverse(int x){ Rev[x] = !Rev[x]; swap(Son[x][0], Son[x][1]);}inline void PushDown(int x){ if (!Rev[x]) return; Rev[x] = false; if (Son[x][0]) Reverse(Son[x][0]); if (Son[x][1]) Reverse(Son[x][1]);}void Rotate(int x){ int y = Father[x], f; PushDown(y); PushDown(x); if (x == Son[y][0]) f = 1; else f = 0; if (isRoot[y]) { isRoot[y] = false; isRoot[x] = true; } else { if (y == Son[Father[y]][0]) Son[Father[y]][0] = x; else Son[Father[y]][1] = x; } Father[x] = Father[y]; Son[y][f ^ 1] = Son[x][f]; if (Son[x][f]) Father[Son[x][f]] = y; Son[x][f] = y; Father[y] = x;}void Splay(int x){ int y; while (!isRoot[x]) { y = Father[x]; if (isRoot[y]) { Rotate(x); break; } if (y == Son[Father[y]][0]) { if (x == Son[y][0]) { Rotate(y); Rotate(x); } else { Rotate(x); Rotate(x); } } else { if (x == Son[y][1]) { Rotate(y); Rotate(x); } else { Rotate(x); Rotate(x); } } }}int Access(int x){ int y = 0; while (x != 0) { Splay(x); PushDown(x); isRoot[Son[x][1]] = true; Son[x][1] = y; if (y) isRoot[y] = false; y = x; x = Father[x]; } return y;}void Make_Root(int x){ int t = Access(x); Reverse(t);}int Find_Root(int x){ int t = Access(x); while (Son[t][0] != 0) t = Son[t][0]; return t;}int main(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) { isRoot[i] = true; Father[i] = 0; } char Str[10]; int a, b, x, y; for (int i = 1; i <= m; ++i) { scanf("%s", Str); Read(a); Read(b); if (strcmp(Str, "Connect") == 0) { Make_Root(a); Splay(a); Father[a] = b; } else if (strcmp(Str, "Destroy") == 0) { Make_Root(a); Access(b); Splay(b); PushDown(b); isRoot[Son[b][0]] = true; Father[Son[b][0]] = 0; Son[b][0] = 0; } else { x = Find_Root(a); y = Find_Root(b); if (x == y) printf("Yes\n"); else printf("No\n"); } } return 0;}

  

转载于:https://www.cnblogs.com/JoeFan/p/4445502.html

你可能感兴趣的文章
Confluence 6 SQL Server 数据库驱动修改
查看>>
Confluence 6 通过 SSL 或 HTTPS 运行 - 备注和问题解决
查看>>
【47.76%】【Round #380B】Spotlights
查看>>
Git(使用码云)
查看>>
分享Java web 开发必游之路
查看>>
IIS初始化(预加载),解决第一次访问慢,程序池被回收问题(转载)
查看>>
Bean的Scope
查看>>
【BZOJ】3142: [Hnoi2013]数列
查看>>
http初探
查看>>
W3C标准以及规范
查看>>
elasticsearch的安装
查看>>
__next__()
查看>>
爬取:中国大学排名
查看>>
聊天室(C++客户端+Pyhton服务器)_1.框架搭设
查看>>
UpdatePanel 内控件 更新“外的”控件【转】
查看>>
[CF508E] Arthur and Brackets
查看>>
[CF1029E] Tree with Small Distances
查看>>
tp5.0中及其常用方法的一些函数方法(自己看)和技巧(不断添加中)
查看>>
美团推荐算法实践
查看>>
Netty官方示例
查看>>