仓鼠找 sugar
仓鼠找 sugar
输出格式
小仓鼠的和他的基(mei)友(zi)sugar 住在地下洞穴中,每个节点的编号为
输出格式
第一行两个正整数
接下来
接下来
输出格式
对于每个询问,如果有公共点,输出大写字母 Y
;否则输出N
。
思路
分析题目,其实就是让我们判断一棵树上
那么如何判断路径是否相交呢?
我们发现,
题目转化成:求一个点是否在两个点的树上简单路径上。
时间复杂度
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN = 1e5 + 7;
const int LOG = 30;
int n,q;
int x,y;
int a,b,c,d;
int fa[MAXN][LOG];
vector<int> tree[MAXN];
int dep[MAXN];
void dfs(int pos,int f){//建树并预处理出深度等信息
fa[pos][0] = f;
dep[pos] = dep[f] + 1;
for(int to : tree[pos]){
if(to != f){
dfs(to,pos);
}
}
}
int Lca(int x,int y){//倍增求LCA
if(dep[y] > dep[x]) swap(x,y);
int delta = dep[x] - dep[y];
int cnt = 0;
while(delta){
if(delta & 1) x = fa[x][cnt];
delta >>= 1;
cnt++;
}
if(x == y) return x;
for(int i = LOG - 2;i >= 0;i--){
if(fa[x][i] != fa[y][i]){
x = fa[x][i],y = fa[y][i];
}
}
return fa[x][0];
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n>>q;
for(int i = 1;i < n;i++){
cin>>x>>y;
tree[x].push_back(y);
tree[y].push_back(x);
}
dfs(1,0);
for(int i = 1;i <= LOG - 2;i++){
for(int j = 1;j <= n;j++){
fa[j][i] = fa[fa[j][i - 1]][i - 1];
}
}
for(int i = 1;i <= q;i++){
cin>>a>>b>>c>>d;
int lca1 = Lca(a,b);
int lca2 = Lca(c,d);
if(lca1 == lca2){
cout<<"Y"<<endl;
continue;
}
if(dep[lca2] > dep[lca1]) swap(lca1,lca2),swap(a,c),swap(b,d);
//判断一个点是否在另外两个点的路径上
int fst = Lca(lca1,c);
int scd = Lca(lca1,d);
if(dep[fst] == dep[lca1] || dep[lca1] == dep[scd]) cout<<"Y"<<endl;
else cout<<"N"<<endl;
}
return 0;
}
本文来自博客园,作者:wyl123ly,转载请注明原文链接:https://www.cnblogs.com/wyl123ly/p/18436561
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】