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

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

设从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. JAVA设计模式之不变模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述不变(Immutable)模式的: 一个对象的状态在对象被创建之后就不再变化,这就是所谓的不变模式. 不变模式的结构 不变模式可增强对象的 ...

  2. 创建sa账号

    ①以windows身份验证的方式默认登陆 ②选择安全性下的登录名中的sa账号,右键选择属性,进行相关项的设置 ③将sa账号的状态中对应的登录项由之前的禁用,改为已启用 ④将sa对应的密码进行修改为自己 ...

  3. AX2012 审批流流转到已停用的域账号导致审批流停止

    AX 2012 中当审批流流转到某个节点时,如果在该节点的审批人的域账号被停用,审批流将会停止,会报如图的错误: 要解决这个问题,得修改标准功能,需要修改SysWorkflow和SysWorkflow ...

  4. java web项目获取各种路径

    1.可以在servlet的init方法里 String path = getServletContext().getRealPath("/"); 这将获取web项目的全路径 例如 ...

  5. 通过案例对 spark streaming 透彻理解三板斧之一: spark streaming 另类实验

    本期内容 : spark streaming另类在线实验 瞬间理解spark streaming本质 一.  我们最开始将从Spark Streaming入手 为何从Spark Streaming切入 ...

  6. Application tried to present a nil modal view controller on target “Current View Controller”解决方案

    情景再现 1,自定义一个storyboard: 打开xcode,按下cmd+N,新建一个Storyboard--->next 将新建立的storyboard命名为:TestViewControl ...

  7. 【229】Raster Calculator - 栅格计算器

    参考:分段函数进行复制,利用语句 参考:ArcGIS栅格计算器 - CSDN 参考:ArcGIS栅格计算器con条件函数使用 参考:ArcGIS栅格计算器 - 电脑玩物 ("lyr" ...

  8. mysql分区查询

    SELECT *FROM INFORMATION_SCHEMA.partitions WHERE table_name='表名' and table_schema='数据库名'

  9. a + b + c 求和

    #include <iostream> int main() { std::cout << "请输入三个数字,以空格分隔,按回车键结束:" << ...

  10. (转载)IOS中UIScrollView的属性和委托方法

    http://www.jizhishusheng.com/?p=453   ---- 以下内容来自 UIScrollView 类负责所有基于 UIKit 的滚动操作一.创建 1. CGRect bou ...