画个图就能多少看出些规律

证明借鉴一下大牛的题解:

设从A到B,经过的深度最小的点为X 同理,C,D的为Y

题目是一个点从A出发到B 一个从C出发到D

那么从A到B可以分解成 先从A到X 再从X到B。。。 C同理

假设能相遇 那么

要么在A到X的过程A,B相遇 要么在X到B的过程A,B相遇

对于在A到X的过程相遇的情况 又可以分解为:

情况1:

在A到X的过程和 C到Y的过程 中A,B相遇 此时相遇点的深度必然大于等于MIN(X深度,Y深度)

情况2:

在A到X的过程和 Y到D的过程 中A,B相遇 此时相遇点的深度必然大于等于MIN (X深度,Y深度)

另一种情况同理。。。

所以显然只要求出MIN=min(lca(a,b),lca(c,d));(lca返回的是两个点公共祖先的最大深度)

假如lca(a,c) lca(a,d) lca(b,c) lca(b,d) 中有任意一个大于等于MIN 的话 那么可以相遇 否则不能

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=,p=;
int n,q,size,father[N][p+],head[M];
int nxt[M],son[M],deep[N];
int read(){
int sum=;
char ch=getchar();
while (ch<''||ch>'')
ch=getchar();
while (ch>=''&&ch<=''){
sum=sum*+ch-'';
ch=getchar();
}
return sum;
}
void uni(int x,int y){
size++;
nxt[size]=head[x];
head[x]=size;
son[size]=y;
}
void swap(int &a,int &b){
int tmp=a;
a=b;
b=tmp;
}
void dfs(int fa,int x){
for (int k=head[x];k;k=nxt[k]){
int y=son[k];
if (y==fa)
continue;
father[y][]=x;
deep[y]=deep[x]+;
dfs(x,y);
}
}
void pre(){
for (int j=;j<=p;j++)
for (int i=;i<=n;i++)
father[i][j]=father[father[i][j-]][j-];
}
int LCA(int x,int y){
if (deep[x]<deep[y])
swap(x,y);
int d=deep[x]-deep[y];
for (int j=p;j>=;j--)
if (d&(<<j))
x=father[x][j];
if (x==y)
return x;
for (int j=p;j>=;j--)
if (father[x][j]!=father[y][j]){
x=father[x][j];
y=father[y][j];
}
return father[x][];
}
int main(){
int u,v;
size=;
n=read();
q=read();
for (int i=;i<n;i++){
u=read();
v=read();
uni(u,v);
uni(v,u);
}
deep[]=;
for (int i=;i<=n;i++)
father[i][]=i;
dfs(,);
pre();
int a,b,c,d;
for (int i=;i<=q;i++){
a=read();
b=read();
c=read();
d=read();
int lca=max(deep[LCA(a,b)],deep[LCA(c,d)]);
int l1=max(deep[LCA(a,c)],deep[LCA(a,d)]);
int l2=max(deep[LCA(b,c)],deep[LCA(b,d)]);
if (max(l1,l2)>=lca)
printf("Y\n");
else
printf("N\n");
}
return ;
}

当然我们也可以判断一下最深的LCA是否在较浅的LCA路径之外

(比如lca_min=lca(a,b),则若deep[a]<lca_max&&deep[b]<lca_max(=lca(c,d))就在外面)

在外面肯定不能相遇

否则再判断一下它是否在其路径上

判断方法,,倍增跳点即可

 #include<cstdio>
#include<cstring>
using namespace std;
const int N=,M=,p=;
int n,q,size,father[N][p+],head[M];
int nxt[M],son[M],deep[N];
int read(){
int sum=;
char ch=getchar();
while (ch<''||ch>'')
ch=getchar();
while (ch>=''&&ch<=''){
sum=sum*+ch-'';
ch=getchar();
}
return sum;
}
void uni(int x,int y){
size++;
nxt[size]=head[x];
head[x]=size;
son[size]=y;
}
void swap(int &a,int &b){
int tmp=a;
a=b;
b=tmp;
}
void dfs(int fa,int x){
for (int k=head[x];k;k=nxt[k]){
int y=son[k];
if (y==fa)
continue;
father[y][]=x;
deep[y]=deep[x]+;
dfs(x,y);
}
}
void pre(){
for (int j=;j<=p;j++)
for (int i=;i<=n;i++)
father[i][j]=father[father[i][j-]][j-];
}
int LCA(int x,int y){
if (deep[x]<deep[y])
swap(x,y);
int d=deep[x]-deep[y];
for (int j=p;j>=;j--)
if (d&(<<j))
x=father[x][j];
if (x==y)
return x;
for (int j=p;j>=;j--)
if (father[x][j]!=father[y][j]){
x=father[x][j];
y=father[y][j];
}
return father[x][];
}
int check(int x,int y){
for (int j=p;j>=;j--)
if (deep[father[x][j]]>=deep[y])
x=father[x][j];
if (x==y)
return ;
return ;
}//deep[x]>deep[y]
int main(){
int u,v;
size=;
n=read();
q=read();
for (int i=;i<n;i++){
u=read();
v=read();
uni(u,v);
uni(v,u);
}
deep[]=;
father[][]=;
dfs(,);
pre();
int a,b,c,d;
for (int i=;i<=q;i++){
a=read();
b=read();
c=read();
d=read();
int lcax=LCA(a,b);
int lcay=LCA(c,d);
if (deep[lcax]<deep[lcay]){
swap(lcax,lcay);
swap(a,c);
swap(b,d);
}//deep[lcax]>deep[lcay]
if (check(lcax,lcay)&&(check(c,lcax)||check(d,lcax)))
printf("Y\n");
else
printf("N\n");
}
return ;
}

最后想说…………LCA的pre()函数……j 如果打错从0循环的话会很GG……

因为它会WA……不一定是RE……

【洛谷P3398】仓鼠找sugar的更多相关文章

  1. 洛谷 P3398 仓鼠找sugar 解题报告

    P3398 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...

  2. 洛谷P3398 仓鼠找sugar [LCA]

    题目传送门 仓鼠找sugar 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而 ...

  3. 洛谷P3398 仓鼠找sugar

    题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴是一个树形结构.这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c) ...

  4. 洛谷——P3398 仓鼠找sugar

    https://www.luogu.org/problem/show?pid=3398#sub 题目描述 小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n.地下洞穴 ...

  5. 洛谷 P3398 仓鼠找sugar —— 树链剖分

    题目:https://www.luogu.org/problemnew/show/P3398 树链剖分一下,路径就变成线段树上的几个区间: 两条路径相交就是线段树上有区间相交,所以在相应位置打个标记, ...

  6. 洛谷 P3398 仓鼠找sugar 题解

    每日一题 day44 打卡 Analysis 首先有一个结论:先找 p1=(a,b),p2=(c,d) 的LCA的深度,在与(a,c),(a,d),(b,c),(b,d)中最深的LCA n的深度比较, ...

  7. 洛谷 [P3398] 仓鼠找sugar

    树剖求LCA 我们可以发现,两条路径ab,cd相交,当且仅当 dep[lca(a,b)]>=dep[lca(c,d)]&(lca(lca(a,b),c)==lca(a,b)||lca(l ...

  8. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

  9. 洛谷p3398仓鼠找suger题解

    我现在爱死树链剖分了 题目 具体分析的话在洛谷blog里 这里只是想放一下改完之后的代码 多了一个son数组少了一个for 少了找size最大的儿子的for #include <cstdio&g ...

  10. 洛谷 3398 仓鼠找sugar——树链剖分

    题目:https://www.luogu.org/problemnew/show/P3398 原来只要把值记录成第几次就行了. 别忘了while(top[a]!=top[b])之后还要走一步. #in ...

随机推荐

  1. FPGA边缘检测

    沿检测技术在项目应用中, 非常低广泛. 如要有效捕获信号跳变沿, 边沿 检测技术的应用是必不可少的.大致如下: (1) 将时钟边沿使能转换为边沿检测使能,使时钟同步化. (2) 捕获信号的突变( UA ...

  2. php路径目录解析函数dirname basename pathinfo区别及实例

    php获取路径.目录或文件名称,我们经常会使用到dirname().basename().pathinfo()这三个函数,本文章向大家详细介绍这三个函数的区别以及使用实例,需要的朋友可以参考一下. d ...

  3. 静态修饰符(关键字static)

    1.Static修饰的方法或变量通常称为类方法和类属性 2.静态方法中不能使用this和super关键字,也不能做为局部变量使用 3.在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成 ...

  4. Codeforces Round #228 (Div. 1) A

    A. Fox and Box Accumulation time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. Delphi七个版本

    第一次Zack Urlocker给我看一款尚未发布的名为Delphi的产品时,我意识到她将改变我的工作—还有许多其他软件开发者的工作. 我过去为使用Windows C++ 库而挣扎,而Delphi过去 ...

  6. 删除空文件夹 清除CS扩展名文件 bat

    删除空文件夹.删的干净.删的彻底. 将下列代码复制到txt中保存.并把后缀.txt命成.bat.然后运行即可. 方案1.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  7. vs2010中将c++控制台程序修改成windows应用程序

    报错:无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用 vs2010环境下将Win32控制台应用程序,改为Win32项目 直接将控制台的mian函数改成 _ ...

  8. Python从题目中学习:List comprehension

    九九乘法表作业其实有更简单的做法,就是用列表推导式. ------------------------------------------------------------------------- ...

  9. 【EF学习笔记10】----------主从表级联操作

    主从表 级联新增 Console.WriteLine("=========主从表 级联新增=========="); using (var db = new Entities()) ...

  10. web项目启动报错Unknown character set: 'utf8mb4' in mysql

    网上一查,有的说是mysql驱动的问题,有的说创建数据库的时候指定utf8编码,换了各种mysql版本,最后换了5.1.6版本的mysql驱动后成功启动!问题解决!OMG