LUOGU P4281 [AHOI2008]紧急集合 / 聚会 (lca)
解题思路
可以通过手玩或打表发现,其实要选的点一定是他们三个两两配对后其中一对的$lca$上,那么就直接算出来所有的$lca$,比较大小就行了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm> using namespace std;
const int MAXN = ; inline int rd(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
} int ans,p,n,m,head[MAXN],cnt,num;
int to[MAXN<<],nxt[MAXN<<];
int id[MAXN],dep[MAXN],top[MAXN],fa[MAXN],siz[MAXN],son[MAXN]; inline void add(int bg,int ed){
to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
} void dfs1(int x,int f,int d){
dep[x]=d,fa[x]=f,siz[x]=;register int maxson=,u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
dfs1(u,x,d+);siz[x]+=siz[u];
if(siz[u]>maxson) {maxson=u;son[x]=u;}
}
} void dfs2(int x,int topf){
top[x]=topf;id[x]=++num;if(!son[x]) return;dfs2(son[x],topf);int u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==fa[x] || u==son[x]) continue;dfs2(u,u);
}
} inline int lca(int x,int y){
while(top[x]!=top[y]){
if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
else y=fa[top[y]];
}
return dep[x]>dep[y]?y:x;
} inline void LCA(int x,int y,int z){
register int tmp,dis,all;tmp=lca(x,y);all=lca(tmp,z);
dis=dep[x]+dep[y]-dep[tmp]+dep[z]-*dep[all];ans=dis;p=tmp;dis+=dep[tmp];
tmp=lca(x,z);dis-=dep[tmp];if(ans>dis) {ans=dis;p=tmp;}
dis+=dep[tmp];tmp=lca(y,z);dis-=dep[tmp];if(ans>dis) {ans=dis;p=tmp;}
} void out(int x){
if(!x) return;
out(x/);putchar(''+x%);
} int main(){
n=rd(),m=rd();int x,y,z;
for(register int i=;i<n;i++){
x=rd(),y=rd();add(x,y),add(y,x);
}
dfs1(,,),dfs2(,);
while(m--) {
x=rd(),y=rd(),z=rd();ans=1e9;
LCA(x,y,z);out(p);putchar(' ');if(!ans) putchar('');else out(ans);
putchar('\n');
}
return ;
}
LUOGU P4281 [AHOI2008]紧急集合 / 聚会 (lca)的更多相关文章
- P4281 [AHOI2008]紧急集合 / 聚会[LCA]
解析 蒟蒻用的办法比较蠢,不如上面的各位大佬,直接化成一个式子了,我还是分类讨论做的. 下面正文. 猜想:最优集合点一定是三点任意两对点对应的路径的交点. 不妨这样想,如果任意两个人经过同一条路径,那 ...
- P4281 [AHOI2008]紧急集合 / 聚会
P4281 [AHOI2008]紧急集合 / 聚会 lca 题意:求3个点的lca,以及3个点与lca的距离之和. 性质:设点q1,q2,q3 两点之间的lca t1=lca(q1,q2) t2=lc ...
- Luogu 4281 [AHOI2008]紧急集合 / 聚会
BZOJ 1832 写起来很放松的题. 首先发现三个点在树上一共只有$3$种形态,大概长这样: 这种情况下显然走到三个点的$lca$最优. 这种情况下走到中间那个点最优. 这种情况下走到$2$最优. ...
- [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条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
- 洛谷 P4281 [AHOI2008] 紧急集合 题解
挺好的一道题,本身不难,就把求两个点的LCA变为求三个点两两求LCA,不重合的点才是最优解.值得一提的是,最后对答案的处理运用差分的思想:假设两点 一点深度为d1,另一点 深度为d2,它们LCA深度为 ...
- 「AHOI2008」「LuoguP4281」紧急集合 / 聚会(LCA
题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
随机推荐
- LeetCode刷题笔记-贪心法-格雷编码
题目描述: 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个位数的差异. 给定一个代表编码总位数的非负整数 n,打印其格雷编码序列.格雷编码序列必须以 0 开头. 来源:力扣(Leet ...
- pandas 使用dataframe 索引项相同时出现bug
使用的是join函数来合并两个dataframe: df=df2.join(df1) bug:columns overlap but no suffix specified: Index([u'muk ...
- 数据分析相关概念(numpy)
矢量 矢量是指一堆形成的集合. 多维数组也叫做矢量化计算. 单独一个数叫做标量 例: import datetime as dt import numpy as np n2=10000 start2 ...
- scala入门基础学习
1.Scala基础语法 区分大小写 类名 - 对于所有的类名的第一个字母要大写.如果需要使用几个单词来构成一个类的名称,每个单词的第一个字母要大写. 方法名称 - 所有的方法名称的第一个字母用小写. ...
- note : Get FilePathName from FILE_OBJECT
转自:http://blog.csdn.net/lostspeed/article/details/11738311 封了一个函数, 从 FILE_OBJECT 中 得到 FilePathName 在 ...
- Android开发 string.xml资源添加参数
挖坑:参考:https://www.cnblogs.com/leelugen/p/6685905.html
- Batch pk Shell - WindowsBatch与LinuxShell比较 [变量符号和关键字]
原文地址:WindowsBatch与LinuxShell比较[变量符号和关键字] 一 简单实例1)batch file @echo off rem output helloworld :: outp ...
- C/C++ 字符、字符串转十六进制(支持中文字符串转换)
#include <string> // std::string #include <sstream> // std::stringstream /** * #purpose ...
- Docker保存日志到本地
其实很简单 docker logs +你需要添加的额外参数 + 容器id >文件名称 然后查看这个文件就可以了,也可以通过ftp协议下载到本地
- 暴力贪心+预处理自动机——cf990E
枚举每种灯管,然后找到代价最小的那种灯管 贪心策略:灯管从0开始向右放置,如果末尾是不能放置灯管的结点,那么要往回找到最近一个可以放置灯管的结点,在那里放置灯管 所以先预处理每个不能放置灯管的结点对应 ...