当前位置: 首页 > news >正文

CF1381D The Majestic Brown Tree Snake/SS251114C. 历遍的树(inverse)

CF1381D The Majestic Brown Tree Snake/SS251114C. 历遍的树(inverse)

题意

给你一棵 \(n\) 个点的树。一条蛇在路径 \((h,t)\) 上。

蛇像火车一样移动。问蛇能否走到路径 \((t,h)\),即反转。

\(h \neq t\)。要线性或者接近线性做法。

思路

蛇会怎么走?

大概是这样的:有一个以 \(u\) 为枢纽的三叉路,整个蛇在其中一条岔路的链上。面向 \(u\) 的为蛇头。

然后蛇正向整个开进另一条岔路,然后再倒着整个开进第三条岔路,最后正向开回去。


我们把合法的枢纽叫做关键点。当存在三条长度大于等于蛇长的岔路时,这个枢纽是合法的。

蛇想要开到这样的三叉路里,发现它很容易走到树的直径。


结论 1:若直径上不存在关键点,则整个树不存在关键点。否则直径上一定存在关键点。

结论 2:若蛇可以到达一个关键点,则蛇可以到达任意关键点。

结论 2-2:若存在答案,蛇一定可以到达直径上的关键点。


证明 1。

img

证毕。


证明 2。

直接借用上图。\((s,t)\) 是直径。

假设 \(u\) 是一个关键点。蛇可以到达 \(u\)。那么蛇直接开进岔路 \(a\),然后开到 \(t\) 那里去即可。

所以一定可以从直径外一个关键点走到直径上的关键点。逆操作显然也成立。

显然也可以从直径上一个关键点走到直径上另一个关键点。


所以先求出树的直径。

找到直径上任意一个关键点 \(u\)

如果蛇可以有一端在 \(u\) 上,则有解。

\(u\) 为根。若 \(h,t\) 是祖孙关系,蛇就可以开到根。

否则求出 \(h,t\) 的 LCA。

在它们变成祖孙关系之前,LCA 不变。

蛇会来回来回地走,每次正着/倒着走到最远的叶子。

如果蛇走到同一个位置,则返回无解。

因为蛇不会走到同一个位置,所以直接模拟即可。

总时间复杂度线性。

code

#include<bits/stdc++.h>
#define sf scanf 
#define pf printf 
#define rep(x,y,z) for(int x=y;x<=z;x++) 
#define per(x,y,z) for(int x=y;x>=z;x--) 
using namespace std;
typedef long long ll;
namespace wing_heart {constexpr int N=1e5+7;int T,n;int h,t,len;int lca;vector<int> to[N];int dep[N],mxdep[N],fa[N],gson[N];int rt;int dfs0(int u,int f) {fa[u]=f;dep[u]=dep[f]+1;int x = u;for(int v : to[u]) if(v^f) {int p = dfs0(v,u);if(dep[p]>dep[x]) x=p;}return x;}void getlen() {len=1;int u=h,v=t;if(dep[u]<dep[v]) swap(u,v);while(dep[u]>dep[v]) ++len, u=fa[u];while(u!=v) len+=2, u=fa[u], v=fa[v];}void findrt(int u,int fa) {dep[u]=dep[fa]+1;mxdep[u]=dep[u];int cnt=0;for(int v : to[u]) if(v^fa) {findrt(v,u);mxdep[u]=max(mxdep[u],mxdep[v]);if(mxdep[v]-dep[u]+1>=len) ++cnt;}if(dep[u]>=len && cnt>=2) rt=u;}void init(int u,int f) {fa[u]=f;dep[u]=dep[f]+1;mxdep[u]=dep[u];gson[u]=0;for(int v : to[u]) if(v^f) {init(v,u);mxdep[u]=max(mxdep[u],mxdep[v]);if(mxdep[v] > mxdep[gson[u]]) gson[u]=v;}}void getlca() {int u=h,v=t;if(dep[u]<dep[v]) swap(u,v);while(dep[u]>dep[v]) u=fa[u];while(u!=v) u=fa[u],v=fa[v];lca=u;}void main() {sf("%d",&T);while(T--) {sf("%d%d%d",&n,&h,&t);rep(i,1,n) to[i].clear();rep(i,1,n-1) {int u,v;sf("%d%d",&u,&v);to[u].push_back(v), to[v].push_back(u);}int u = dfs0(1,0); // 找到直径的一端getlen(); // 求出蛇长rt=0;findrt(u,0); // 找到关键点if(!rt) {puts("NO");continue;}init(rt,0);getlca();int deph=dep[h],dept=dep[t];while(lca!=h && lca!=t) {int cdeph=mxdep[h];if(cdeph-dep[lca]+1>=len) {t=lca;break;}while(gson[h]) h=gson[h], t=fa[t];int cdept=mxdep[t];if(cdept-dep[lca]+1>=len) {h=lca;break;}while(gson[t]) t=gson[t], h=fa[h];if(cdeph==deph && cdept==dept) {puts("NO");break;}deph=cdeph, dept=cdept;}if(lca==h || lca==t) puts("YES");}}
}
int main() {wing_heart :: main();
}
http://www.zskr.cn/news/49865.html

相关文章:

  • 如何将 Android 联系人备份到 Mac 的 4 种容易
  • 分布式之RabbitMQ的使用(3)QueueBuilder - 详解
  • 2025年市面上口碑好的出国留学中介机构哪家强,全球联申/名校录取/留学就业一体化/背景提升/语言培训中介哪家好
  • 网络犯罪新手段:黑客如何利用IT技术实施货物盗窃
  • 很多争论不是认知问题,而是数学问题
  • 代码制作数学动画 python manim jjmpeg - 何苦
  • 题解:P13573 [CCPC 2024 重庆站] Pico Park
  • 实用指南:12-机器学习与大模型开发数学教程-第1章1-4 导数与几何意义
  • docker登录容器镜像仓库
  • 吴恩达深度学习课程二: 改善深层神经网络 第三周:超参数调整,批量标准化和编程框架(一)超参数调整
  • 恭喜自己,挑战成功! - Ghost
  • 如何在测试覆盖不足后补充验证
  • 完整教程:PDFBox - PDDocument 与 byte 数组、PDF 加密
  • Web应用模糊测试完全指南
  • 【HT-086-Div.2】错乱的集合
  • WEditor的使用方法
  • 感情粉末沿着试管边缘 在祝福中逐渐分解 加热认知离子重新排列 于底部悲伤沉淀
  • flask: 抛出异常
  • 雪地奔驰全等级提升所需经验一览
  • 2025皮肤亚健康管理品牌最新专业推荐:科技赋能健康美新生态
  • 深入解析:Vue3 路由配置和使用与讲解(超级详细)
  • HubSpot如何规模化推进AI编码助手应用
  • 完整教程:OpenHarmony内核基础:LiteOS-M内核与POSIX/CMSIS接口
  • 常量指针 和 指针常量 - const pointer and pointer to const
  • 11.14模拟赛
  • 实用指南:云计算生态及学习方向和就业领域方向
  • 2025年11月徐州AI GEO平台综合评测与权威推荐
  • 2025年国内徐州宣传片公司品牌权威推荐榜单
  • 好题集 (2) - LG P4550 收集邮票
  • 腾讯元宝如何导出内容为文档