传送门

解题思路

可以通过手玩或打表发现,其实要选的点一定是他们三个两两配对后其中一对的$lca$上,那么就直接算出来所有的$lca$,比较大小就行了。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cstdlib>
  5. #include<algorithm>
  6.  
  7. using namespace std;
  8. const int MAXN = ;
  9.  
  10. inline int rd(){
  11. int x=,f=;char ch=getchar();
  12. while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
  13. while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
  14. return f?x:-x;
  15. }
  16.  
  17. int ans,p,n,m,head[MAXN],cnt,num;
  18. int to[MAXN<<],nxt[MAXN<<];
  19. int id[MAXN],dep[MAXN],top[MAXN],fa[MAXN],siz[MAXN],son[MAXN];
  20.  
  21. inline void add(int bg,int ed){
  22. to[++cnt]=ed,nxt[cnt]=head[bg],head[bg]=cnt;
  23. }
  24.  
  25. void dfs1(int x,int f,int d){
  26. dep[x]=d,fa[x]=f,siz[x]=;register int maxson=,u;
  27. for(register int i=head[x];i;i=nxt[i]){
  28. u=to[i];if(u==f) continue;
  29. dfs1(u,x,d+);siz[x]+=siz[u];
  30. if(siz[u]>maxson) {maxson=u;son[x]=u;}
  31. }
  32. }
  33.  
  34. void dfs2(int x,int topf){
  35. top[x]=topf;id[x]=++num;if(!son[x]) return;dfs2(son[x],topf);int u;
  36. for(register int i=head[x];i;i=nxt[i]){
  37. u=to[i];if(u==fa[x] || u==son[x]) continue;dfs2(u,u);
  38. }
  39. }
  40.  
  41. inline int lca(int x,int y){
  42. while(top[x]!=top[y]){
  43. if(dep[top[x]]>dep[top[y]]) x=fa[top[x]];
  44. else y=fa[top[y]];
  45. }
  46. return dep[x]>dep[y]?y:x;
  47. }
  48.  
  49. inline void LCA(int x,int y,int z){
  50. register int tmp,dis,all;tmp=lca(x,y);all=lca(tmp,z);
  51. dis=dep[x]+dep[y]-dep[tmp]+dep[z]-*dep[all];ans=dis;p=tmp;dis+=dep[tmp];
  52. tmp=lca(x,z);dis-=dep[tmp];if(ans>dis) {ans=dis;p=tmp;}
  53. dis+=dep[tmp];tmp=lca(y,z);dis-=dep[tmp];if(ans>dis) {ans=dis;p=tmp;}
  54. }
  55.  
  56. void out(int x){
  57. if(!x) return;
  58. out(x/);putchar(''+x%);
  59. }
  60.  
  61. int main(){
  62. n=rd(),m=rd();int x,y,z;
  63. for(register int i=;i<n;i++){
  64. x=rd(),y=rd();add(x,y),add(y,x);
  65. }
  66. dfs1(,,),dfs2(,);
  67. while(m--) {
  68. x=rd(),y=rd(),z=rd();ans=1e9;
  69. LCA(x,y,z);out(p);putchar(' ');if(!ans) putchar('');else out(ans);
  70. putchar('\n');
  71. }
  72. return ;
  73. }

LUOGU P4281 [AHOI2008]紧急集合 / 聚会 (lca)的更多相关文章

  1. P4281 [AHOI2008]紧急集合 / 聚会[LCA]

    解析 蒟蒻用的办法比较蠢,不如上面的各位大佬,直接化成一个式子了,我还是分类讨论做的. 下面正文. 猜想:最优集合点一定是三点任意两对点对应的路径的交点. 不妨这样想,如果任意两个人经过同一条路径,那 ...

  2. P4281 [AHOI2008]紧急集合 / 聚会

    P4281 [AHOI2008]紧急集合 / 聚会 lca 题意:求3个点的lca,以及3个点与lca的距离之和. 性质:设点q1,q2,q3 两点之间的lca t1=lca(q1,q2) t2=lc ...

  3. Luogu 4281 [AHOI2008]紧急集合 / 聚会

    BZOJ 1832 写起来很放松的题. 首先发现三个点在树上一共只有$3$种形态,大概长这样: 这种情况下显然走到三个点的$lca$最优. 这种情况下走到中间那个点最优. 这种情况下走到$2$最优. ...

  4. [AHOI2008]紧急集合 / 聚会(LCA)

    [AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通 ...

  5. LCA【p4281】[AHOI2008]紧急集合 / 聚会

    Description 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等 ...

  6. 【题解】洛谷P4281 [AHOI2008] 紧急集合(求三个点LCA)

    洛谷P4281:https://www.luogu.org/problemnew/show/P4281 思路 答案所在的点必定是三个人所在点之间路径上的一点 本蒟蒻一开始的想法是:先求出2个点之间的L ...

  7. [AHOI2008]紧急集合 / 聚会

    题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...

  8. 洛谷 P4281 [AHOI2008] 紧急集合 题解

    挺好的一道题,本身不难,就把求两个点的LCA变为求三个点两两求LCA,不重合的点才是最优解.值得一提的是,最后对答案的处理运用差分的思想:假设两点 一点深度为d1,另一点 深度为d2,它们LCA深度为 ...

  9. 「AHOI2008」「LuoguP4281」紧急集合 / 聚会(LCA

    题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...

随机推荐

  1. plugin python was not installed: Cannot download ''

    problem: plugin python was not installed: Cannot download ''........ 1. the first method of resoluti ...

  2. AtCoder ABC 130F Minimum Bounding Box

    题目链接:https://atcoder.jp/contests/abc130/tasks/abc130_f 题目大意 给定地图上 N 个点的坐标和移动方向,它们会以每秒 1 个单位的速度移动,设 A ...

  3. linux 网络监控软件nethogs iftop

    1.nethogs yum -y install nethogs 装上了这个工具之后,使用起来就非常简单了.敲入nethogs 就会给出所有的信息.看下面的例子. root@ubuntu2:~# ne ...

  4. sklearn提供的自带数据集

    sklearn 的数据集有好多个种 自带的小数据集(packaged dataset):sklearn.datasets.load_<name> 可在线下载的数据集(Downloaded ...

  5. pycharm快捷键表

    快捷键 作用 ctrl(command)+c 复制 ctrl+v 粘贴 ctrl+z 撤销 ctrl+x 剪切,默认整行 ctrl+a 全选 ctrl+f 查找:选中批量修改 shift+ctrl+z ...

  6. vue项目使用history模式打包应该注意的地方

    1.在config/index.js中将assetsPublicPath原来的’/‘修改为‘./’. build: { env: require('./prod.env'), index: path. ...

  7. Visual Studio Git代码管理环境部署

    Visual Studio 2010 部署Git代码管理环境. 第一:首先做Git的安装和环境部署 1.下载并安装Git软件,在windows环境下的Git叫做“msysGit”,官网地址为https ...

  8. split的用法

    split用法返回的是数组 使用split('')根据空格返回数组 使用split()返回一个完整的数组 使用split("",3)返回前三项,是单个的字母 不过要注意: 使用sp ...

  9. thinkphp empty标签

    empty标签用于判断某个变量是否为空,用法: 大理石平台检验标准 <empty name="name"> name为空值 </empty> 如果判断没有赋 ...

  10. LUOGU P4042 [AHOI2014/JSOI2014]骑士游戏 (spfa+dp)

    传送门 解题思路 首先设\(f[x]\)表示消灭\(x\)的最小花费,那么转移方程就是 \(f[x]=min(f[x],\sum f[son[x]] +s[x])\),如果这个转移是一个有向无环图,那 ...