传送门

1.并查集骗分(数据太水,比正解还快。。。)

我们知道,并查集有一步操作叫“路径压缩”,但是本题的并查集我们不能路径压缩,否则就无法进行Destroy操作。那每一步操作我们应该怎么做呢?

对于Connect x y操作,先把x变成集合的根,之后root[x] = y;

对于Destroy x y操作,先把x变成集合的根,此时root[y]必然为x,令root[y] = y即可。

对于Query x y操作,看看x和y所在集合的根是不是一样的就好了。

那么如何把x变成集合的根呢?只要把从x到根路径上的每一条边反向即可,所以不能进行路径压缩。

其实并查集的解法也有用 lct 的思想的。

在这里,并查集中的两点之间的边就表示连接两个洞穴之间的边,非常的直接。。

注意一个细节 : 题目中说——无论通道怎么改变,任意时刻任意两个洞穴之间至多只有一条路径

也就是说不会有环!这也正是能用并查集做的原因之一。

——代码

 #include <cstdio>
#include <iostream>
#define N 10001 int n, m;
int f[N]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int find(int x)
{
while(x ^ f[x]) x = f[x];
return x;
} inline void make_root(int x, int c)
{
if(x ^ f[x]) make_root(f[x], x);
f[x] = c;
} int main()
{
int i, j, x, y, fx, fy;
char s[];
n = read();
m = read();
for(i = ; i <= n; i++) f[i] = i;
for(i = ; i <= m; i++)
{
scanf("%s", s);
x = read();
y = read();
if(s[] == 'Q') find(x) == find(y) ? puts("Yes") : puts("No");
else if(s[] == 'C') make_root(x, x), f[x] = y;
else make_root(x, x), f[y] = y;
}
return ;
}

2.lct(正解)

就是模板啦

——代码

 #include <cstdio>
#include <iostream>
#define N 10001
#define swap(x, y) ((x) ^= (y) ^= (x) ^= (y)) int n, m;
int f[N], rev[N], son[N][], s[N], size[N]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline bool isroot(int x)
{
return son[f[x]][] ^ x && son[f[x]][] ^ x;
} inline int get(int x)
{
return son[f[x]][] == x;
} inline void pushdown(int x)
{
if(x && rev[x])
{
swap(son[x][], son[x][]);
if(son[x][]) rev[son[x][]] ^= ;
if(son[x][]) rev[son[x][]] ^= ;
rev[x] = ;
}
} inline void rotate(int x)
{
int old = f[x], oldf = f[old], wh = get(x); if(!isroot(old))
son[oldf][son[oldf][] == old] = x;
f[x] = oldf; son[old][wh] = son[x][wh ^ ];
f[son[old][wh]] = old; son[x][wh ^ ] = old;
f[old] = x;
} inline void splay(int x)
{
int i, fa, t = ;
s[++t] = x;
for(i = x; !isroot(i); i = f[i]) s[++t] = f[i];
for(i = t; i >= ; i--) pushdown(s[i]);
for(; !isroot(x); rotate(x))
if(!isroot(fa = f[x]))
rotate(get(x) == get(fa) ? fa : x);
} inline void access(int x)
{
for(int t = ; x; t = x, x = f[x]) splay(x), son[x][] = t;
} inline void reverse(int x)
{
access(x);
splay(x);
rev[x] ^= ;
} inline int find(int x)
{
access(x);
splay(x);
while(son[x][]) x = son[x][];
return x;
} inline void link(int x, int y)
{
reverse(x);
f[x] = y;
splay(x);
} inline void cut(int x, int y)
{
reverse(x);
access(y);
splay(y);
son[y][] = f[x] = ;
} int main()
{
int i, j, x, y;
char s[];
n = read();
m = read();
for(i = ; i <= m; i++)
{
scanf("%s", s);
x = read();
y = read();
if(s[] == 'Q') find(x) == find(y) ? puts("Yes") : puts("No");
if(s[] == 'C') link(x, y);
if(s[] == 'D') cut(x, y);
}
return ;
}

[luoguP2147] [SDOI2008]Cave 洞穴勘测(并查集 || lct)的更多相关文章

  1. 【bzoj2049】[Sdoi2008]Cave 洞穴勘测——线段树上bfs求可撤销并查集

    题面 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 12030 Solved: 6024 Desc ...

  2. 【bzoj2049】[Sdoi2008]Cave 洞穴勘测 link-cut-tree

    2016-05-30  11:04:51 学习了link-cut-tree 二中神犇封禹的讲义感觉讲的超级清晰易懂啊(没有的可以q窝 算是模板吧 #include<bits/stdc++.h&g ...

  3. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 LCT

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnli ...

  4. bzoj 2049: [Sdoi2008]Cave 洞穴勘测 动态树

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3119  Solved: 1399[Submit] ...

  5. 【LCT】BZOJ2049 [SDOI2008]Cave 洞穴勘测

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 10059  Solved: 4863[Submit ...

  6. BZOJ_2049_[Sdoi2008]Cave 洞穴勘测_LCT

    BZOJ_2049_[Sdoi2008]Cave 洞穴勘测_LCT Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由 ...

  7. bzoj 2049: [Sdoi2008]Cave 洞穴勘测 (LCT)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2049 题面: 2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 1 ...

  8. BZOJ 2049: [Sdoi2008]Cave 洞穴勘测 (动态树入门)

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1528  Solved: 644[Submit][ ...

  9. 2049: [Sdoi2008]Cave 洞穴勘测

    2049: [Sdoi2008]Cave 洞穴勘测 Time Limit: 10 Sec  Memory Limit: 259 MB Submit: 7475  Solved: 3499 [Submi ...

随机推荐

  1. 一些常用的HTML标签

    由于本人目前没有系统学习,日常碰见哪个有用就记下来. pre标签 可定义预格式化的文本,在pre元素中的文本会保留空格和换行符.比如我们展示源代码的时候,只要放一个pre标签,然后把代码直接复制.粘贴 ...

  2. 一步一步教你用IntelliJ IDEA 搭建SSM框架(1)

    1.基本概念 SSM框架指:Spring MVC + Spring + MyBatis Spring MVC是一种web层mvc框架,用于替代servlet,处理|响应请求,获取表单参数,表单校验等 ...

  3. Java获取yml里面的配置

    #yml文件配置systemPath: #档案系统地址 dossier: http://127.0.0.1:8088/ //调用说明 配置文件里必须包含节点 否则项目无法启动 @Value(" ...

  4. Caesars Cipher-freecodecamp算法题目

    Caesars Cipher(凯撒密码.移位密码) 要求 字母会按照指定的数量来做移位. 一个常见的案例就是ROT13密码,字母会移位13个位置.由'A' ↔ 'N', 'B' ↔ 'O',以此类推. ...

  5. pm2日志记录和日志分割

    pm2日志记录和日志分割 pm2介绍 pm2是nodejs进程管理工具,现在基本是node生产服务器的标准选择,可以帮助我们实现node多进程服务,开启的多个实例自动实现负载均衡. 最重要的是保证no ...

  6. fread()创建文件和file_exists()文件缓存问题

    ①fread('','w')调用当文件不存在时创建文件,其中参数使用了fread('',"w")导致无法创建文件,修改单引号之后操作正常. ②项目当中新建日志文件,需要判断日志文件 ...

  7. Golang 简单静态web服务器

    直接使用 net.http 包,非常方便 // staticWeb package main import ( "fmt" "net/http" "s ...

  8. python入门:py2.x里面除法或乘法这么写就可以计算小数点后面结果

    #!/usr/bin/env python # -*- coding:utf-8 -*- #py2.x里面除法或乘法这么写就可以计算小数点后面结果,更精确future(未来,译音:非忧车) divis ...

  9. DeepFaceLab: SSE,AVX, OpenCL 等版本说明!

    Deep Fake Lab早期只有两个版本,一个是专门正对NVIDIA显卡的CUDA9的版本,另一个是支持CPU的版本. 三月初该项目作者对tenserFlow,Cuda的版本进行了升级,预编译的软件 ...

  10. python3通过Beautif和XPath分别爬取“小猪短租-北京”租房信息,并对比时间效率(附源代码)

    爬虫思路分析: 1. 观察小猪短租(北京)的网页 首页:http://www.xiaozhu.com/?utm_source=baidu&utm_medium=cpc&utm_term ...