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条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
 
随机推荐
- 【2019年06月28日】A股最便宜的股票
			
查看更多A股最便宜的股票:androidinvest.com/CNValueTop/ 经典价值三因子选股: 市盈率PE.市净率PB 和 股息分红率,按照 1:1:1的权重,选择前10大最便宜的股票. ...
 - sts问题合集
			
背景:用来记录在使用sts过程中遇到的相关问题 Version 当前jdk版本号 of the JVM is not suitable for the this product.Version:1.8 ...
 - samba服务器安装测试
			
samba服务器安装 1.简介 作用:samba文件服务器允许通过网络跨步同的操作系统进行文件共享. 2.安装samba服务器 $ sudo apt-get update $ sudo apt-get ...
 - Docker下安装kafka
			
先看一下有哪些选择 额,没有官方的,但是可以根据stars来找一个,大多数人都选择第一个,我们看一下GitHub就知道了. 第一个:https://github.com/wurstmeister/ka ...
 - os-enviroment
			
pip3 install PyUserInput ping 是不带协议的
 - golang 使用 protobuf 的教程
			
1.下载protobuf的编译器protoc 地址: https://github.com/google/protobuf/releases window: 下载: protoc-3.3.0-w ...
 - java ASM
			
一.什么是ASM ASM是一个java字节码操纵框架,它能被用来动态生成类或者增强既有类的功能.ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为.J ...
 - Excel导出,添加有效性
			
#region 添加有效性 DataTable dt = LAbll.LogisticsAccounts(DeptId); //查数据 if (dt.Rows.Count < 20) //有效 ...
 - Elasticsearch 、 Logstash以及Kibana 分布式日志
			
搭建ELK日志分析平台(上)—— ELK介绍及搭建 Elasticsearch 分布式集群 ELK简介: ELK是三个开源软件的缩写,分别为:Elasticsearch . Logstash以及Kib ...
 - Django:RestFramework之-------权限
			
4.restframework-权限 4.1权限: 权限在单个视图应用. class MyPermission(object): """认证类""&q ...