cogs 2098. [SYOI 2015] Asm.Def的病毒 LCA 求两条路径是否相交
2098. [SYOI 2015] Asm.Def的病毒
★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out 简单对比
时间限制:1 s 内存限制:256 MB
【题目描述】
“这就是我们最新研制的,世界上第一种可持久化动态计算机病毒,‘创世纪’。”方教授介绍道。
“哦。”主席面无表情地点点头。
“‘创世纪’无法真正杀死透明计算网络,但是可以把它变成傻子。可惜透明计算网络能轻松地辨认出病毒,所以我建议……”
“为什么不伪装呢?”Asm.Def说。
“当然不行,它比我们更懂伪装。”
“我是说,把我们的病毒伪装成杀毒软件。”
方教授震惊地盯着Asm.Def看了一会。“你是个天才。”

Asm.Def想把病毒伪装成杀毒软件,入侵透明计算网络。透明计算网络的文件结构是一棵N个节点的树,每个病毒可以入侵一条路径上的所有节点。但如果两个病毒入侵了同一个节点,由于它们伪装成了杀毒软件,就会自相残杀。Asm.Def不希望这样的情况发生,所以他需要仔细制定入侵计划。为此,他需要频繁地询问,两条路径是否经过同一个节点(即是否相交)。
【输入格式】
第一行两个整数N,Q。
接下来N-1行,每行两个整数a,b,表示(a,b)是树上的一条边。
接下来Q行,每行四个整数s1,t1,s2,t2,表示询问s1~t1的路径是否与s2~t2的路径相交。
【输出格式】
对每个询问,若相交则输出一行”YES”,否则输出一行”NO”。
【样例输入】
6 5
1 2
1 3
2 4
4 5
4 6
1 1 5 6
1 2 6 3
2 3 5 6
6 4 3 1
4 3 1 2
【样例输出】
NO
YES
NO
NO
YES
【提示】
N,Q<=1000.
1<=s1,t1,s2,t2<=N。
【来源】
“Asm.Def战记之夏威夷”杯
这一题的题面看起来可真是好玩啊
这一道题真是一个神奇的题
题意就是判断一下两条路径是否相交 而且还要多次询问 所以必须要有一格效率很高的方法 不能暴力
这一道题的标签看起来好可怕!LCA!???满脸疑惑

哈哈↑↑题面都在斗图 我也来一个
所以这一道题到底跟LCA有什么关系呢?
。。。。(沉默中)
我默默地翻了一下别人的代码
终于发现了奥妙所在
别急别急 我们来看一个图吧(本图借用自weixin_34362991)
这一道题的思路是这个样子的
就是说有两条路径 2-6 and 5-3 很显然是相交的 (看到那个3了吗!!!)
首先我们把能看到的lca瞅一遍
lca(2,6)=1
lca(3,5)=6
很显然这个时候6的深度是要比1的深度要大的
那我们就取6为"LLCCAA"
LLCCAA和2的lca是1
LLCCAA和6的lca是6
这个6和LLCCAA相等 所以他们是相交的 (好神奇!?)
其实也肥肠好理解
就是说这条lca更深的路径的lca 与 较浅的路径的两个端点的lca如果有其中的任何一个与更深路径的两个端点的lca的lca等于更深路径两个端点的lca 就是香蕉了
也就是说 相当于这一条更浅得路延伸到了这条更深的路的lca的下面 也就是相交了嘛
(↑是不是很简单)
自己结合那个图觉悟一会就明白了哦
太开心了!3分钟A样例 随之AC~(尽管树链剖分那一段是复制的 啦啦啦(~ ̄▽ ̄)~)
本人拙见如有疏漏之处敬请指正
代码如下 树链剖分一波:
#include<bits/stdc++.h>
#define maxn 1005
using namespace std;
int n,Ques;
vector<int> v[maxn];
int size[maxn],dfn[maxn],pos[maxn],vis[maxn],fa[maxn],son[maxn],top[maxn],dep[maxn];
int cnt=;
void Dfs(int x)
{
size[x]=;//首先以x为根的子树的大小size 先设为1 就是目前已x为根的子树只有x自己
for(int i=;i<v[x].size();i++)
{
int y=v[x][i];//son
if(!size[y])//这里的意思其实就是如果这个儿子还没有访问过
//因为我们可以看到每一次dfs的开始才会把size设一个数值 一开始应该都是0的
//所以这里就可以直接当做一个vis标记用了
{
dep[y]=dep[x]+;//记录深度 son的深度 是father的深度+1
fa[y]=x;//记录son的father 是谁
Dfs(y);
size[x]+=size[y];//更新x为根的子树的大小
if(size[son[x]]<size[y])//son存储的是重儿子
son[x]=y;//更新重儿子
}
}
}
void Dfs(int x,int tp)
{
top[x]=tp;//top数组是用来记录一条重链的顶端
dfn[++cnt]=x;//dfn是记录第cnt个访问的点是x
pos[x]=cnt;//pos记录第x个点是第cnt个访问的 当然在本题中不会用到
if(son[x])//如果有重儿子 先走重儿子
Dfs(son[x],tp);
for(int i=;i<v[x].size();i++)
{
int y=v[x][i];
if(!top[y])//走轻儿子
Dfs(y,y);
}
}
int lca(int x,int y)
{
while(top[x]!=top[y])//先跳到同一条重链上
{
if(dep[top[x]]<dep[top[y]])
swap(x,y);
x=fa[top[x]];
}
if(dep[x]>dep[y])//保证x的深度更小 x就是lca
swap(x,y);
return x;
}
inline int read()
{
int X=; bool flag=; char ch=getchar();
while(ch<''||ch>'') {if(ch=='-') flag=; ch=getchar();}
while(ch>=''&&ch<='') {X=(X<<)+(X<<)+ch-''; ch=getchar();}
if(flag) return X;
return ~(X-);
}
int main()
{
freopen("asm_virus.in","r",stdin);
freopen("asm_virus.out","w",stdout);
n=read(),Ques=read();
for(int i=,x,y;i<n;i++)
{
x=read(),y=read();
v[x].push_back(y);
v[y].push_back(x);
}
Dfs();Dfs(,);
for(int i=,x,y,u,v;i<=Ques;i++)
{
x=read(),y=read(),u=read(),v=read();
int lca1=lca(x,y),lca2=lca(u,v);
if(dep[lca1]<dep[lca2]) swap(lca1,lca2),swap(x,u),swap(y,v);
if(lca(lca1,u)==lca1||lca(lca1,v)==lca1)
puts("YES");
else
puts("NO");
}
return ;
}
cogs 2098. [SYOI 2015] Asm.Def的病毒 LCA 求两条路径是否相交的更多相关文章
- LCA -cogs2098 [SYOI 2015] Asm.Def的病毒
题目链接:http://cogs.pro:8081/cogs/problem/problem.php?pid=vQXmxVaPU [题目描述] “这就是我们最新研制的,世界上第一种可持久化动态计算机病 ...
- cogs——2098. Asm.Def的病毒
2098. Asm.Def的病毒 ★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “这就 ...
- COGS 2098. Asm.Def的病毒
★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “这就是我们最新研制的,世界上第一种可持 ...
- COGS——C2098. Asm.Def的病毒
http://www.cogs.pro/cogs/problem/problem.php?pid=2098 ★☆ 输入文件:asm_virus.in 输出文件:asm_virus.out ...
- COGS——T2084. Asm.Def的基本算法
http://cogs.pro/cogs/problem/problem.php?pid=2084 ★☆ 输入文件:asm_algo.in 输出文件:asm_algo.out 简单对比时间 ...
- COGS 2091. Asm.Def的打击序列
★★★ 输入文件:asm_lis.in 输出文件:asm_lis.out 简单对比时间限制:4 s 内存限制:256 MB [题目描述] 白色圆柱形的“蓝翔”号在虚空中逐渐变大,一声沉 ...
- COGS 2084. Asm.Def的基本算法
★☆ 输入文件:asm_algo.in 输出文件:asm_algo.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “有句美国俗语说,如果走起来像鸭子,叫起来像 ...
- COGS 2082. Asm.Def谈笑风生
★ 输入文件:asm_talk.in 输出文件:asm_talk.out 简单对比时间限制:2 s 内存限制:256 MB [题目描述] “人呐都不知道,自己不可以预料,直升机刚一出圣 ...
- cogs——2084. Asm.Def的基本算法
2084. Asm.Def的基本算法 ★☆ 输入文件:asm_algo.in 输出文件:asm_algo.out 简单对比时间限制:1 s 内存限制:256 MB [题目描述] “有句 ...
随机推荐
- python基础五之字典
python数据的可变性 通过数据的可变性,可将数据分为可变数据类型和不可变数据类型. 可变数据类型:list,dict (不可哈希) 不可变数据类型:元祖,bool,int,str (可哈希) py ...
- Notice: Use of undefined constant - assumed ' '
昨天看手册的时候有两个范例,懒得写了,直接复制,测试一下,结果报Notice; 反复检查无果,最后, 手动敲了一遍,居然正常了,汗.... 总结:偷懒害人
- js 替换指定位置的字符串
不多bb,直接代码 //str:原始字符串,index,开始位置,changeStr,改变后的字 changeStr(str,index,changeStr){ return str.substr(0 ...
- 2019-9-2-win10-uwp-列表模板选择器
title author date CreateTime categories win10 uwp 列表模板选择器 lindexi 2019-09-02 12:57:38 +0800 2018-2-1 ...
- Linux 内核Ksets 对象
很多情况, 一个 kset 看来象一个 kobj_type 结构的扩展; 一个 kset 是一个嵌入到相 同类型结构的 kobject 的集合. 但是, 虽然 struct kobj_type 关注的 ...
- Linux USB 和 sysfs
由于单个 USB 物理设备的复杂性, 设备在 sysfs 中的表示也非常复杂. 物理 USB 设备 (通过 struct usb_device 表示)和单个 USB 接口(由 struct usb_i ...
- js 快速取整
我们要将23.8转化成整数 有哪些方法呢 比如 Math.floor( ) 对数进行向下取整 它返回的是小于或等于函数参数,并且与之最接近的整数 Math.floor(5.1) 返回值 //5 M ...
- HDU - 1005 Number Sequence (矩阵快速幂)
A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mo ...
- IdentityServer4 Clients
原文地址 Clients 的定义 Client是指那些从 identityserver获取 token的应用 通常需要为client定义下面通用的设置 唯一的client id secret, 如果需 ...
- sed工具
SED是一个非交互式文本编辑器,它可对文本文件和标准输入进行编辑,标准输入可以来自键盘输入.文本重定向.字符串.变量,甚至来自于管道的文本,与VIM编辑器类似,它一次处理一行内容,Sed可以编辑一个或 ...