[Luogu 3398] 仓鼠找sugar
[Luogu 3398] 仓鼠找sugar
又是 LCA…
前两天死活写不过的一个题今天终于顺手切了。
思路嘛参考了一楼题解。
就是说,对于 a
, b
, c
, d
四个点,
令 x
= LCA(a, b), y
= LCA(c, d),
两条路径有交叉,当且仅当 c
, d
至少一个在 x
的子树下,且 a
, b
至少一个在 y
的子树下。
由于我是 HLD 求的 LCA,第一遍 DFS 时顺手把子树大小求了,后边判断在不在一棵子属下的时候就可以很方便了。
就这样。
#include <algorithm>
#include <cstdio>const int MAXN = 100010; int n, q; struct Graph
{struct Edge{int to; Edge *next; Edge(int to, Edge* next): to(to), next(next) {}~Edge(void){if(next != NULL)delete next; }}*head[MAXN]; Graph(int n){std :: fill(head + 1, head + n + 1, (Edge*)NULL); }~Graph(void){for(int i = 1; i <= n; ++i)delete head[i]; }void AddEdges(int u, int v){head[u] = new Edge(v, head[u]); head[v] = new Edge(u, head[v]); }
}*G; namespace HLD
{int num; struct Node{int depth, father, son, top, size, DFN; }s[MAXN]; void DFS1(int u, int k){s[u].depth = k; s[u].size = 1; int v; for(Graph :: Edge *i = G -> head[u]; i != NULL; i = i -> next)if(!s[v = i -> to].size){DFS1(v, k + 1); s[u].size += s[v].size; s[v].father = u; if(s[v].size > s[s[u].son].size)s[u].son = v; }}void DFS2(int u, int top){s[u].top = top; s[u].DFN = ++num; if(s[u].son)DFS2(s[u].son, top); int v; for(Graph :: Edge *i = G -> head[u]; i != NULL; i = i -> next)if(!s[v = i -> to].DFN)DFS2(v, v); }void Init(void){DFS1(1, 1); DFS2(1, 1); }int LCA(int x, int y){int a, b; while((a = s[x].top) ^ (b = s[y].top))if(s[a].depth > s[b].depth)x = s[a].father; elsey = s[b].father; return s[x].depth < s[y].depth ? x : y; }bool Range(int x, int y){return s[x].DFN <= s[y].DFN && s[y].DFN < s[x].DFN + s[x].size; }bool Query(int a, int b, int c, int d){int x = LCA(a, b), y = LCA(c, d); return (Range(x, c) || Range(x, d)) && (Range(y, a) || Range(y, b)); }
}int main(void)
{scanf("%d %d", &n, &q); G = new Graph(n); for(int i = 1, u, v; i < n; ++i){scanf("%d %d", &u, &v); G -> AddEdges(u, v); }HLD :: Init(); for(int i = 1, a, b, c, d; i <= q; ++i){scanf("%d %d %d %d", &a, &b, &c, &d); puts(HLD :: Query(a, b, c, d) ? "Y" : "N"); }return 0;
}
谢谢阅读。
转载于:https://www.cnblogs.com/Capella/p/9912634.html
[Luogu 3398] 仓鼠找sugar相关推荐
- luogu P3398 仓鼠找sugar
P3398 仓鼠找sugar 224通过 860提交 题目提供者 fjzzq2002 标签 云端↑ 难度 提高+/省选- 时空限制 1s / 128MB 题目描述 小仓鼠的和他的基(mei)友(zi) ...
- luogu P3398 仓鼠找sugar(树链剖分、求树上两条路径有没有交点,爽!)
整理的算法模板合集: ACM模板 舒服,一次敲160行代码一次编译通过一次AC是真的爽! 虽然这道题可以当作简单版的树链剖分板子题了hhh 要求的是两条路径有没有交点,正解是LCA玄学证明,看的我有点 ...
- 洛谷 3398 仓鼠找sugar 【模板】判断树上两链有交
[题解] 题意就是判断树上两条链是否有交.口诀是"判有交,此链有彼祖".即其中一条链的端点的Lca在另一条链上. 我们设两条链的端点的Lca中深度较大的为L2,对L2与另一条链的两 ...
- 【luogu3398】 仓鼠找sugar [LCA 倍增]
P3398 仓鼠找sugar 长期不学竞赛...导致1mol的低级错误出现 把f数组开为f[N][20] 写错判断 我烂了QAQ我好瘟死于低级错误久久无法判断出来 如果两条路径相交,那么一定有一条路径 ...
- 【洛谷】【lca+结论】P3398 仓鼠找sugar
[题目描述:] 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室 ...
- 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)
洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...
- P3398 仓鼠找sugar (倍增LCA)
P3398 仓鼠找sugar (倍增LCA) 前言:本来想找 t a r j a n tarjan tarjan的题做下的,结果这个标签有 t a r j a n tarjan tarjan,却是 l ...
- 洛谷 P3398 仓鼠找 sugar
仓鼠找 sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为 1 1 1~ n n n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室( a a ...
- P3398 仓鼠找sugar(LCA,树剖)
题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...
最新文章
- Linux下 memcached安装以及启动
- 查杀DeDe数据库后门 网站安全狗DeDe专杀工具
- bond-vlan-bridge
- hdu3177 贪心
- 位运算判断奇偶数_位运算符判断奇偶
- python2与python3代码互相转化时注意事项
- seata xid是什么_阿里开源的分布式事务框架 Seata
- php+apache 和 php+nginx的区别
- ubuntu 18.04 卸载 mysql 过程记录
- go语言中文件的操作:
- 求教:.Net Framework 3.5 SP1安装失败
- c swap方法在哪个库里面_IOT操作系统用C++库的经验总结
- Mysql可视化工具安装及使用说明
- pp助手苹果版本_这可能是最简单的下载APP历史版本方法(支持iOS和安卓)
- 微擎系统BUG漏洞解决方法汇总(原创)
- 【檀越剑指大厂--mysql】mysql高阶篇
- Mbit/s MB/s MiB/s单位
- 面向对象的正式与非正式解释!
- artemis服务_Artemis
- Java异步编程Future应用