BZOJ 1832、1787 洛谷 4281 [AHOI2008]紧急集合
【题解】
题目要求找到一个集合点,使3个给定的点到这个集合点的距离和最小,输出集合点的编号以及距离。
设三个点为A,B,C;那么我们可以得到Dis=dep[A]+dep[B]+dep[C]-dep[Lca]-dep[Lca2]*2;其中Lca是A,B的最近公共祖先;Lca2是Lca与C的最近公共祖先。那么为了使Dis最大,必须使dep[Lca]+dep[Lca2]*2最大。那么我们只需找出A,B,C两两之间Lca中Dep最大的作为集合点就可以了。
#include<cstdio>
#include<algorithm>
#define N 500010
#define rg register
using namespace std;
int n,m,tot,last[N],dep[N],son[N],size[N],fa[N],top[N];
struct edge{
int to,pre;
}e[N<<1];
inline int read(){
int k=0,f=1; char c=getchar();
while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
return k*f;
}
inline void add(int x,int y){
e[++tot]=(edge){y,last[x]}; last[x]=tot;
}
void dfs1(int x){
size[x]=1; dep[x]=dep[fa[x]]+1;
for(rg int i=last[x],to;i;i=e[i].pre)if((to=e[i].to)!=fa[x]){
fa[to]=x; dfs1(to);
size[x]+=size[to];
if(size[to]>size[son[x]]) son[x]=to;
}
}
void dfs2(int x,int tp){
top[x]=tp;
if(son[x]) dfs2(son[x],tp);
for(rg int i=last[x],to;i;i=e[i].pre)
if((to=e[i].to)!=fa[x]&&to!=son[x]) dfs2(to,to);
}
inline int lca(int x,int y){
int f1=top[x],f2=top[y];
while(f1!=f2){
if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
x=fa[f1]; f1=top[x];
}
return dep[x]<dep[y]?x:y;
}
int main(){
n=read(); m=read();
for(rg int i=1;i<n;i++){
int u=read(),v=read();
add(u,v); add(v,u);
}
dfs1(1); dfs2(1,1);
// for(rg int i=1;i<=m;i++) printf("%d\n",lca(read(),read()));
for(rg int i=1;i<=m;i++){
int a=read(),b=read(),c=read();
int l1=lca(a,b),l2=lca(a,c),l3=lca(b,c);
if(dep[l1]>=dep[l2]&&dep[l1]>=dep[l3]){
printf("%d ",l1);
printf("%d\n",dep[a]+dep[b]+dep[c]-dep[l1]-(dep[lca(l1,c)]<<1));
continue;
}
if(dep[l2]>=dep[l1]&&dep[l2]>=dep[l3]){
printf("%d ",l2);
printf("%d\n",dep[a]+dep[b]+dep[c]-dep[l2]-(dep[lca(l2,b)]<<1));
continue;
}
if(dep[l3]>=dep[l1]&&dep[l3]>=dep[l2]){
printf("%d ",l3);
printf("%d\n",dep[a]+dep[b]+dep[c]-dep[l3]-(dep[lca(l3,a)]<<1));
continue;
}
}
return 0;
}
BZOJ 1832、1787 洛谷 4281 [AHOI2008]紧急集合的更多相关文章
- 【题解】洛谷P4281 [AHOI2008] 紧急集合(求三个点LCA)
洛谷P4281:https://www.luogu.org/problemnew/show/P4281 思路 答案所在的点必定是三个人所在点之间路径上的一点 本蒟蒻一开始的想法是:先求出2个点之间的L ...
- 洛谷 P4281 [AHOI2008] 紧急集合 题解
挺好的一道题,本身不难,就把求两个点的LCA变为求三个点两两求LCA,不重合的点才是最优解.值得一提的是,最后对答案的处理运用差分的思想:假设两点 一点深度为d1,另一点 深度为d2,它们LCA深度为 ...
- Luogu 4281 [AHOI2008]紧急集合 / 聚会
BZOJ 1832 写起来很放松的题. 首先发现三个点在树上一共只有$3$种形态,大概长这样: 这种情况下显然走到三个点的$lca$最优. 这种情况下走到中间那个点最优. 这种情况下走到$2$最优. ...
- [poi2011]bzoj 2277 —— strongbox·[洛谷3518]
·问题描述· 有一个密码箱,0到n-1中的某些数是它的密码.且满足:如果a和b都是它的密码,那么(a+b)%n也是它的密码.某人试了k次密码,前k-1次都失败了,最后一次成功. 问:该密码箱最多有多少 ...
- [bzoj] 3263 陌上花开 洛谷 P3810 三维偏序|| CDQ分治 && CDQ分治讲解
原题 定义一个点比另一个点大为当且仅当这个点的三个值分别大于等于另一个点的三个值.每比一个点大就为加一等级,求每个等级的点的数量. 显然的三维偏序问题,CDQ的板子题. CDQ分治: CDQ分治是一种 ...
- 「洛谷3338」「ZJOI2014」力【FFT】
题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...
- BZOJ2120/洛谷P1903 [国家集训队] 数颜色 [带修改莫队]
BZOJ传送门:洛谷传送门 数颜色 题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R ...
- 洛谷 P3307: bzoj 3202: [SDOI2013] 项链
题目传送门:洛谷P3307.这题在bzoj上是权限题. 题意简述: 这题分为两个部分: ① 有一些珠子,每个珠子可以看成一个无序三元组.三元组要满足三个数都在$1$到$m$之间,并且三个数互质,两个珠 ...
- bzoj 4816: 洛谷 P3704: [SDOI2017]数字表格
洛谷很早以前就写过了,今天交到bzoj发现TLE了. 检查了一下发现自己复杂度是错的. 题目传送门:洛谷P3704. 题意简述: 求 \(\prod_{i=1}^{N}\prod_{j=1}^{M}F ...
随机推荐
- 手推FP-growth (频繁模式增长)算法------挖掘频繁项集
一.频繁项集挖掘为什么会出现FP-growth呢? 原因:这得从Apriori算法的原理说起,Apriori会产生大量候选项集(就是连接后产生的),在剪枝时,需要扫描整个数据库(就是给出的数据),通过 ...
- 关于Java泛型的?和 T 的区别
java中的?号指未知的类型:而T指具体类型 泛型问号(?)未知的类型就是可以指定当前问号(?)所代表的类,可以指定上限(extends)和下限(super) 泛型T指已经具体知道了类型,就是不能指定 ...
- linux rpm 安装
1.rpm 安装rpm -ivh package_name-i:install的意思-v:查看更详细的安装信息-h:以安装信息栏显示安装进度rpm -ivh package_name --test 2 ...
- 2017杭电多校06Rikka with Graph
Rikka with Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- 273 Integer to English Words 整数转换英文表示
将非负整数转换为其对应的英文表示,给定的输入是保证小于 231 - 1 的.示例:123 -> "One Hundred Twenty Three"12345 -> & ...
- win7升级到win10不能上网解决方法
不要相信360的网络诊断了,都是坑货,没有什么用.下面的方法亲测有效.如君不行,那估计是win10版本不一样,原因另寻. 1.以管理员身份运行CMD,输入netsh winsock reset. 2. ...
- Android基础夯实--重温动画(一)之Tween Animation
心灵鸡汤:真正成功的人生,不在于成就的大小,而在于你是否努力地去实现自我,喊出自己的声音,走出属于自己的道路. 摘要 不积跬步,无以至千里:不积小流,无以成江海.学习任何东西我们都离不开扎实的基础知识 ...
- LR接口测试---基于http协议之get/post
get请求代码: //=====================get interface======================== 以http状态码方式: //获取返回的HTTP状态码判断请求 ...
- Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!
Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!
- 【Python-2.7】大小写转换函数
字母大小写是编程过程中经常遇到的问题,如下函数可以灵活的进行大小写转换: title():把单词首字母转换为大写: upper():把每个字母转换为大写: lower():把每个字母转换为小写. 示例 ...