【题目描述:】

小仓鼠的和他的基(mei)友(zi)sugar住在地下洞穴中,每个节点的编号为1~n。地下洞穴是一个树形结构。这一天小仓鼠打算从从他的卧室(a)到餐厅(b),而他的基友同时要从他的卧室(c)到图书馆(d)。他们都会走最短路径。现在小仓鼠希望知道,有没有可能在某个地方,可以碰到他的基友?

小仓鼠那么弱,还要天天被zzq大爷虐,请你快来救救他吧!

【输入格式:】

第一行两个正整数n和q,表示这棵树节点的个数和询问的个数。

接下来n-1行,每行两个正整数u和v,表示节点u到节点v之间有一条边。

接下来q行,每行四个正整数a、b、c和d,表示节点编号,也就是一次询问,其意义如上。

【输出格式:】

对于每个询问,如果有公共点,输出大写字母“Y”;否则输出“N”。

输入样例#: 

输出样例#:
Y
N
Y
Y
Y

输入输出样例

【算法分析:】

对于四个点a, b, c, d,判断a->b, c->d这两条路径是否有重合的点,

容易想到分别求出(a, b), (c, d)的最近公共祖先,只要其中一个点对的lca在另一个点对的最短路径上,则这两条路径相交.

那如何判断lca与路径的位置关系呢?

首先想到树上差分,但每次O(n)维护一个前缀和肯定会超时,弃掉.

我们通过模拟可以得出这样的结论

 若一个点x在路径s->t上,则:

  1.   deep[x] ≥ deep[lca(s, t)]
  2.   lca(x, s) = x 或 lca(x, t) = x

对于结论1.,由于x可以是lca(a, b)和lca(c, d)中的任意一个,所以自然是选择深度大的lca作为x

对于结论2.,选定了x之后只需两个判断即可.

【代码:】

 //仓鼠找sugar
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; const int MAXN = + ;
const int K = + ; int n, Q;
int deep[MAXN], f[MAXN][K];
int edge_num, head[MAXN];
struct Edge {
int to, nxt;
}h[MAXN << ]; inline int read() {
int x = , f = ; char ch = getchar();
while(ch<'' || ch>'') {
if(ch == '-') f = -;
ch = getchar();
}
while(ch>='' && ch<='')
x = (x<<) + (x<<) + ch-, ch = getchar();
return x * f;
} inline void Add(int from, int to) {
h[++edge_num].to = to;
h[edge_num].nxt = head[from];
head[from] = edge_num;
} inline void build(int u) {
for(int i=head[u]; i!=-; i=h[i].nxt) {
if(!deep[h[i].to]) {
deep[h[i].to] = deep[u] + ;
f[h[i].to][] = u;
build(h[i].to);
}
}
} inline void fill() {
for(int j=; j<K; ++j)
for(int i=; i<=n; ++i)
f[i][j] = f[f[i][j - ]][j - ];
} inline int LCA(int a, int b) {
if(deep[a] > deep[b]) swap(a, b);
for(int i=K-; i>=; --i)
if(deep[f[b][i]] >= deep[a]) b = f[b][i];
if(a == b) return a;
for(int i=K-; i>=; --i)
if(f[a][i] != f[b][i])
a = f[a][i], b = f[b][i];
return f[b][];
} int main() {
memset(head, -, sizeof(head));
n = read(), Q = read();
for(int i=; i<n; ++i) {
int x = read(), y = read();
Add(x, y), Add(y, x);
}
deep[] = ;
build();
fill();
while(Q--) {
int a = read(), b = read(), c = read(), d = read();
int lca1 = LCA(a, b), lca2 = LCA(c, d);
if(deep[lca1] > deep[lca2]) {
swap(a, c); swap(b, d);
swap(lca1, lca2);
}
if(LCA(lca2, a) == lca2 || LCA(lca2, b) == lca2) puts("Y");
else puts("N");
}
}

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

  1. 【树链剖分/倍增模板】【洛谷】3398:仓鼠找sugar

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

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

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

  3. P3398 仓鼠找sugar

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

  4. P3398 仓鼠找sugar(树链剖分)

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

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

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

  6. 洛谷 P3398 仓鼠找sugar 题解

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

  7. luogu P3398 仓鼠找sugar [LCA]

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

  8. 洛谷10月月赛Round.1| P3398 仓鼠找sugar[LCA]

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

  9. 洛谷P3398 仓鼠找sugar

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

随机推荐

  1. Docker(一):入门教程

    2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业. 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?本文就来详细解释,帮助大家理解它,还带有简单 ...

  2. java图形用户界面之列表框

    列表框通过Swing组件JList产生,其总是在屏幕上占据固定行数的空间.如果要得到列表框中被选中的元素,只需调用getSelectedValuesList(),它可以产生一个字符串数组,内容为被选中 ...

  3. 通过UA判断,对滚动条样式进行不同的操作

    浏览器滚动条的默认样式比较丑,有些情况下,又不能直接overflow:hidden掉. 本文阐述如何通过 document.styleSheets[0].insertRule 简单的实现pc端和移动端 ...

  4. webapi 后台跳转 后台输出html和script

    1.跳转 [HttpGet]public HttpResponseMessage LinkTo(){ HttpResponseMessage resp = new HttpResponseMessag ...

  5. 进度条(Progressbar)

    进度条(Progressbar) 提供如下一些样式改变进度条的外观 @android:style/Widget.ProgressBar.Horizontal(水平进度条) @android:style ...

  6. csv注入漏洞原理&&实战

    前言  为了找工作,巩固巩固知识.本文会介绍 csv 注入漏洞的原理,最后给出一个示例.  正文 在 csv 文件 和 xlsx 文件中的每一项的值如果是 =, @, +, - 就会被 excel 识 ...

  7. ecloipse背景修改豆沙

    Eclipse背景色的修改 Eclipse背景色的修改,修改为豆沙色  值是85 123 205 一.修改编辑区   ①这个比较简单一般都会不多说. 1.首先点击Window 然后选择Preferen ...

  8. 记录下使用iis7代理node.js写的网站程序

    昨天晚上一个学弟的紧急求救,说了自己接的单子做了一个网站,使用了自己熟悉的技术——node.js+mongdb,但当看到部署环境惊呆了,是 windows+sqlserver.这些都不是关键,关键是服 ...

  9. leetCode题解之根据字符出现的频率排序

    1.题目描述 Given a string, sort it in decreasing order based on the frequency of characters. Example 1: ...

  10. Django之自定义权限

    官方解释 Custom permissions¶ To create custom permissions for a given model object, use the permissions  ...