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

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

我居然把swap写成了switch

如果路径相交,那么一定有LCA(a,b)在路径c,d上,或LCA(c,d)在路径a,b上

如果x在路径a,b上,需要满足条件:

dpth[x] >= dpth[LCA(a,b)] 

LCA(a,x)=x 或 LCA(b,x)=x

就这样,求出LCA后分别判断一下即可

代码如下

#include
#include
#include
#include
#define MogeKo qwqusing namespace std;const int maxn = 2e5+10;int n,q,x,y,a,b,c,d,e,f,cnt;int dpth[maxn],p[maxn][25];int head[maxn],to[maxn],nxt[maxn];void add(int x,int y) { to[++cnt] = y; nxt[cnt] = head[x]; head[x] = cnt;}void dfs(int x,int fa) { dpth[x] = dpth[fa]+1; p[x][0] = fa; for(int i = 1; (1<
<= dpth[x]; i++) p[x][i] = p[p[x][i-1]][i-1]; for(int i = head[x]; i; i = nxt[i]) { if(dpth[to[i]]) continue; if(to[i] == fa) continue; dfs(to[i],x); }}int lca(int a,int b) { if(dpth[a] < dpth[b]) swap(a,b); for(int i = 20; i >= 0; i--) if(dpth[a] - (1<
= dpth[b]) a = p[a][i]; if(a == b) return a; for(int i = 20; i >= 0; i--) if(p[a][i] != p[b][i]) a = p[a][i],b = p[b][i]; return p[a][0];}bool check(int a,int b,int c,int d) { if(dpth[d] >= dpth[c]) if(lca(a,d)==d || lca(b,d)==d) return true; return false;}int main() { scanf("%d%d",&n,&q); for(int i = 1; i <= n-1; i++) { scanf("%d%d",&x,&y); add(x,y),add(y,x); } dfs(1,-1); while(q--) { scanf("%d%d%d%d",&a,&b,&c,&d); e = lca(a,b); f = lca(c,d); if(check(a,b,e,f) || check(c,d,f,e)) printf("Y\n"); else printf("N\n"); } return 0;}
View Code

 

转载于:https://www.cnblogs.com/mogeko/p/11221187.html

你可能感兴趣的文章
Vue.js——60分钟组件快速入门(下篇)
查看>>
【算法习作】字符串处理两例
查看>>
Day 29 _模块二 -hashlib_configparse_logging
查看>>
leetcode 19 删除链表的倒数第n个节点
查看>>
配置centos6.0为Router
查看>>
JavaScript闭包学习笔记(ife2015spring)
查看>>
Flask 初识
查看>>
工厂模式
查看>>
拦截器
查看>>
sdk
查看>>
DOM操作
查看>>
用python绘制质粒图谱
查看>>
C语言三联序列(trigraph sequences)
查看>>
luogu_1004 方格取数
查看>>
ZBrush的双十一来了,然鹅...
查看>>
linux mint使用中的问题解决记录
查看>>
babel浏览器源码地址
查看>>
【linux基础】vim快速移动光标至行首行尾、第一行和最后一行
查看>>
SQL Server 表字段值转列名 示例
查看>>
leetcode 139. Word Break
查看>>