博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[Luogu 3398] 仓鼠找sugar
阅读量:5366 次
发布时间:2019-06-15

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

[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 
#include
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; else y = 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

你可能感兴趣的文章
bzoj 4260: Codechef REBXOR (01 Trie)
查看>>
学好python
查看>>
css-IE中的border-radius和box-shadow
查看>>
利用bootstrap和webform的异步CRUD及分页
查看>>
HDUOJ 1879继续畅通工程(并查集)
查看>>
OC12_自动释放池
查看>>
Saiku资源帖
查看>>
解决手机页面中点击文本框,网页放大问题
查看>>
2-5
查看>>
牛客多校3 A-PACM Team(状压降维+路径背包)
查看>>
HDU - 4284 Travel(floyd+状压dp)
查看>>
1027 制作表格
查看>>
Android之Socket通信、List加载更多、Spinner下拉列表
查看>>
面向对象的介绍与特性
查看>>
typing-python用于类型注解的库
查看>>
20189215 2018-2019-2 《密码与安全新技术专题》第13周作业
查看>>
第四周作业
查看>>
一、HTML基础
查看>>
蓝牙进阶之路 (002) - HC-05与HC-06的AT指令的区别(转)
查看>>
mysql的limit经典用法及优化
查看>>