P4281 [AHOI2008]紧急集合 / 聚会[LCA]
解析
蒟蒻用的办法比较蠢,不如上面的各位大佬,直接化成一个式子了,我还是分类讨论做的。
下面正文。
猜想:最优集合点一定是三点任意两对点对应的路径的交点。
不妨这样想,如果任意两个人经过同一条路径,那么就要支付双倍的价钱,为了使支付的钱最少,我们就要使得这种情况出现的最少。由于图是一颗树,如果选择三点交点,一定不会出现这样的边。
那么如何求交点呢?
可以分成两种情况:
1、三个点都在以某个点为根的子树中。
2、有两个点在以某个点为根的子树,另一个点在它上面。
判断比较麻烦,由于无法知道三点确切的相对位置关系,所以这就导致情况2分出来好几种判断法则。实际上它们本质是一样的。
参考代码
吸氧最优解第二页,不吸氧掉到最后一页去了(摊。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 500010
#define MOD 2520
#define E 1e-12
using namespace std;
inline int read()
{
int f=1,x=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct rec{
int next,ver;
}g[N<<1];
int head[N],tot,n,m;
inline void add(int x,int y)
{
g[++tot].ver=y;
g[tot].next=head[x],head[x]=tot;
}
int size[N],top[N],son[N],fa[N],dep[N],id[N],cnt;
inline void dfs1(int x,int f,int deep)
{
size[x]=1,fa[x]=f,dep[x]=deep;
int maxson=-1;
for(int i=head[x];i;i=g[i].next){
int y=g[i].ver;
if(y==f) continue;
dfs1(y,x,deep+1);
size[x]+=size[y];
if(maxson<size[y]) maxson=size[y],son[x]=y;
}
}
inline void dfs2(int x,int topf)
{
id[x]=++cnt,top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(int i=head[x];i;i=g[i].next){
int y=g[i].ver;
if(y==fa[x]||y==son[x]) continue;
dfs2(y,y);
}
}
inline 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]) swap(x,y);
return x;
}
inline int dist(int x,int y){return dep[x]+dep[y]-2*dep[lca(x,y)];}//两点距离
int main()
{
n=read(),m=read();
for(int i=1;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs1(1,0,1);dfs2(1,1);//树剖LCA
while(m--){
int x=read(),y=read(),z=read();
int k1=lca(x,y),k2=lca(y,z),k3=lca(x,z);//f**k lca
if(k1==k2&&k2==k3)//case 1
printf("%d %d\n",k1,dep[x]+dep[y]+dep[z]-3*dep[k1]);
else if(k1!=k2&&k2!=k3&&k1==k3)
printf("%d %d\n",k2,dist(k2,x)+dist(y,z));
else if(k1!=k3&&k3!=k2&&k1==k2)
printf("%d %d\n",k3,dist(k3,y)+dist(x,z));
else if(k2!=k1&&k1!=k3&&k2==k3)//case 2
printf("%d %d\n",k1,dist(k1,z)+dist(x,y));
}
return 0;
}
P4281 [AHOI2008]紧急集合 / 聚会[LCA]的更多相关文章
- LUOGU P4281 [AHOI2008]紧急集合 / 聚会 (lca)
传送门 解题思路 可以通过手玩或打表发现,其实要选的点一定是他们三个两两配对后其中一对的$lca$上,那么就直接算出来所有的$lca$,比较大小就行了. #include<iostream> ...
- P4281 [AHOI2008]紧急集合 / 聚会
P4281 [AHOI2008]紧急集合 / 聚会 lca 题意:求3个点的lca,以及3个点与lca的距离之和. 性质:设点q1,q2,q3 两点之间的lca t1=lca(q1,q2) t2=lc ...
- [AHOI2008]紧急集合 / 聚会(LCA)
[AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通 ...
- LCA【p4281】[AHOI2008]紧急集合 / 聚会
Description 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等 ...
- 【题解】洛谷P4281 [AHOI2008] 紧急集合(求三个点LCA)
洛谷P4281:https://www.luogu.org/problemnew/show/P4281 思路 答案所在的点必定是三个人所在点之间路径上的一点 本蒟蒻一开始的想法是:先求出2个点之间的L ...
- [AHOI2008]紧急集合 / 聚会
题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
- Luogu 4281 [AHOI2008]紧急集合 / 聚会
BZOJ 1832 写起来很放松的题. 首先发现三个点在树上一共只有$3$种形态,大概长这样: 这种情况下显然走到三个点的$lca$最优. 这种情况下走到中间那个点最优. 这种情况下走到$2$最优. ...
- 洛谷 P4281 [AHOI2008] 紧急集合 题解
挺好的一道题,本身不难,就把求两个点的LCA变为求三个点两两求LCA,不重合的点才是最优解.值得一提的是,最后对答案的处理运用差分的思想:假设两点 一点深度为d1,另一点 深度为d2,它们LCA深度为 ...
- 「AHOI2008」「LuoguP4281」紧急集合 / 聚会(LCA
题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
随机推荐
- [技术博客] Springboot的Controller类使用
Springboot的Controller类使用 @Controller:处理http请求. 代码: @Controller public class QuestionController { ... ...
- .net core 读取配置文件的值
.net core中的配置文件可以存一些自定义的值,我们需要去读取 在配置中添加json: "name": "sealee", "Connection ...
- Maven 教程(10)— Maven依赖详解
原文地址:https://blog.csdn.net/liupeifeng3514/article/details/79545022 1.何为依赖? 比如你是个男的,你要生孩子,呸呸呸…男的怎么生孩子 ...
- 管道通信——FIFO的代码实现
一.用到的函数 umask linux中的 umask 函数主要用于:在创建新文件或目录时 屏蔽掉新文件或目录不应有的访问允许权限. 文件的访问允许权限共有9种,分别是 ...
- 搭建zipkin并以mysql的方式存储数据
zipkin以mysql的方式存储 (centos+java8+mysql+zipkin2.3.1) 前言: 这篇教程用于搭建已mysql作为存储的zipkin.(还不知道zipkin是什么的小伙伴请 ...
- ELK学习笔记之Kibana权限控制和集群监控
详细请参考如下四篇博客,注意ELK6中移除了Xpack的默认账户和密码,需要手动设置 Kibana安全特性之权限控制 ELK 集群 Kibana 使用 X-Pack 权限控制,监控集群状态,警报,监视 ...
- c#栈的用法
栈是一种重要的线性结构,栈和队列是限定插入和删除只能在表的“端点”进行的线性表 –栈的元素必须“后进先出”. –栈的操作只能在这个线性表的表尾进行. –注:对于栈来说,这个表尾称为栈的栈顶(top), ...
- C# Newtonsoft.Json 你必须知道的一些用法
最近在做接口开发,对方团队开发了一个Web API 的接口,传输数据的格式是 JSON.当时看到这个东西,感觉很简单,也没想什么,没用多久就完成了我的功能,我完成的功能很简单,就是获取数据,然后把数据 ...
- 一. jmeter
1.性能测试概述 1.1 主要方向是测试系统在一定负荷压力下,系统的响应时间,吞吐量,稳定性,系统的可扩展性等性能指标. 结合应用的架构和实现细节找出问题,并最终确认问题得到解决的过程. 目的: 1. ...
- datax分析与思考(一)
Datax 总体流程图 先看执行的第一个步骤: 在最上层抽象类,这个里面相当于获取全局公共信息,java入口部分就是这个Engine的main方法直接启动 Engine 启动 com.alibaba. ...