[题解]P3398 仓鼠找 sugar

P3398 仓鼠找 sugar

题意简述

给定一个\(N\)个节点的树形结构。接下来有\(q\)次询问,每次询问给定\(4\)个节点\(a,b,c,d\),请计算\(a\)\(b\)的简单路径和\(c\)\(d\)的简单路径是否有相交的节点。对于每个询问,输出Y/N表示答案。

解题思路 & Code

通过手玩样例可以发现,\(a\sim b\)\(c\sim d\)有相交节点,当且仅当\(lca(a,b)\)\(c\sim d\)上,或者\(lca(c,d)\)\(a\sim b\)上。

那么我们怎么判断一个点在一条路径上呢?

我们设路径端点为\(a,b\),要判断节点\(c\)是否在\(a\sim b\)上。

通过寻找规律,我们可以把“\(c\)\(a\sim b\)上”归纳为下面\(2\)种情况:

  • \(c\)\(a\sim lca(a,b)\)上:\(lca(a,c)=c\)\(lca(a,b)=lca(b,c)\)
  • \(c\)\(b\sim lca(a,b)\)上:\(lca(b,c)=c\)\(lca(a,b)=lca(a,c)\)

简单证明一下:\(lca(a,c)=c\)说明\(c\)\(a\)的祖先,而\(lca(b,c)=lca(a,b)\)又说明\(lca(a,b)\)\(c\)的祖先。也就是说\(c\)\(a\sim lca(a,b)\)上。\(b\)同理。

只要满足其一,就说明\(c\)\(a\sim b\)上。我们把判断的过程写成函数onpath(a,b,c),对于每次询问,如果onpath(a,b,lca(c,d))||onpath(c,d,lca(a,b)),则输出Y,否则输出N

就酱。

这里LCA用倍增实现,总时间复杂度\(O((N+q)\log N)\)

点击查看代码
#include<bits/stdc++.h>
#define N 100010
using namespace std;
int dep[N],fa[N][20];
int n,q;
vector<int> G[N];
void dfs(int u,int father){
dep[u]=dep[father]+1;
fa[u][0]=father;
for(int i=1;i<20;i++)
fa[u][i]=fa[fa[u][i-1]][i-1];
for(int i:G[u])
if(i!=father) dfs(i,u);
}
int lca(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
for(int i=19;i>=0;i--)
if(dep[fa[u][i]]>=dep[v])
u=fa[u][i];
if(u==v) return v;
for(int i=19;i>=0;i--)
if(fa[u][i]!=fa[v][i])
u=fa[u][i],v=fa[v][i];
return fa[u][0];
}
bool onpath(int a,int b,int c){
int ab=lca(a,b),bc=lca(b,c),ac=lca(a,c);
return (ac==c&&ab==bc)||(bc==c&&ab==ac);
}
int main(){
cin>>n>>q;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
G[u].emplace_back(v);
G[v].emplace_back(u);
}
dfs(1,0);
while(q--){
int a,b,c,d;
cin>>a>>b>>c>>d;
if(onpath(a,b,lca(c,d))||onpath(c,d,lca(a,b)))
cout<<"Y\n";
else cout<<"N\n";
}
return 0;
}

附:
给出“\(c\)\(a\sim b\)上”归纳出的两种情况也可以这样处理:

  • \(c\)\(a\sim lca(a,b)\)上:\(lca(a,c)=c\)\(dep[c]\ge dep[lca(a,b)]\)
  • \(c\)\(b\sim lca(a,b)\)上:\(lca(b,c)=c\)\(dep[c]\ge dep[lca(a,b)]\)

简单证明一下:\(lca(a,c)=c\)说明\(c\)\(a\)的祖先,而又有\(dep[c]\ge dep[lca(a,b)]\),将\(c\)限制在了\(a\)\(lca(a,b)\)之间。\(b\)同理。

posted @   Sinktank  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
2025-3-6 6:10:32 TOP-BOTTOM-THEME
Enable/Disable Transition
Copyright © 2023 ~ 2024 Sinktank - 1328312655@qq.com
Illustration from 稲葉曇『リレイアウター/Relayouter/中继输出者』,by ぬくぬくにぎりめし.
点击右上角即可分享
微信分享提示