\(\\\)

\(Description\)


一棵\(N\)个节点的树,每条边权都为\(1\)。

\(M\)组询问,每次给出三个点\(A_i,B_i,C_i\),求从三个点分别出发,移动到同一个点的路径最小权值和。

  • \(N,M\in [1,5\times10^5]\)

\(\\\)

\(Solution\)


  • 如果是两个点,显然在两点到\(Lca\)的路径上任意位置会合都是花费最小的方案。扩展到三个点,我们猜测最优答案也是产生在两点\(Lca\)或一段路径上。手玩一会样例或者自己造一点数据,可以发现一个事实:三点两两求\(Lca\),必然至少有两个\(Lca\)是同一个点,形象化的表示:

    图中所示的是最一般的情况,可以发现两个相同的\(Lca\)的深度一定不会大于单独的\(Lca\)的深度,因为相同的\(Lca\)产生于,单独的\(Lca\)与不产生这个单独的\(Lca\)的点求\(Lca\)。

  • 此时方案就显然了,图中所有单色的边是一定要被走一次的,如果在图中的\(L2\)处会和,双色的边会被\(b,c\)各走一次,而若在单独的\(Lca\)处会和,双色的边只会走一次,所以我们直接判断出单独的\(Lca\),让第三个点\((a)\)去往那里集合就好,路径长度可以在找\(Lca\)的时候顺便求出。

\(\\\)

\(Code\)


#include<cmath>
#include<queue>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 500010
#define R register
#define gc getchar
using namespace std; inline int rd(){
int x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
} int n,m,t,tot,d[N],hd[N],f[N][20];
struct edge{int to,nxt;}e[N<<1]; inline void add(int u,int v){
e[++tot].to=v; e[tot].nxt=hd[u]; hd[u]=tot;
} queue<int> q;
inline void bfs(){
q.push(1); d[1]=1;
while(!q.empty()){
int u=q.front(); q.pop();
for(R int i=hd[u],v;i;i=e[i].nxt)
if(!d[v=e[i].to]){
d[v]=d[u]+1; f[v][0]=u;
for(R int i=1;i<=t;++i) f[v][i]=f[f[v][i-1]][i-1];
q.push(v);
}
}
} inline pair<int,int> lca(int u,int v){
int res=0;
if(d[u]>d[v]) u^=v^=u^=v;
for(R int i=t;~i;--i) if(d[f[v][i]]>=d[u]) v=f[v][i],res+=(1<<i);
if(u==v) return make_pair(u,res);
for(R int i=t;~i;--i)
if(f[u][i]!=f[v][i]) v=f[v][i],u=f[u][i],res+=(1<<(i+1));
return make_pair(f[u][0],res+2);
} int main(){
t=log2(n=rd())+1; m=rd();
for(R int i=1,u,v;i<n;++i){
u=rd(); v=rd(); add(u,v); add(v,u);
}
bfs();
pair<int,int> l1,l2,l3;
for(R int i=1,a,b,c;i<=m;++i){
a=rd(); b=rd(); c=rd();
l1=lca(a,b); l2=lca(a,c); l3=lca(b,c);
if(l1.first==l2.first) printf("%d %d\n",l3.first,l3.second+lca(l3.first,a).second);
else if(l1.first==l3.first) printf("%d %d\n",l2.first,l2.second+lca(l2.first,b).second);
else if(l2.first==l3.first) printf("%d %d\n",l1.first,l1.second+lca(l1.first,c).second);
}
return 0;
}

[ AHOI 2008 ] Meet的更多相关文章

  1. 「BZOJ 1831」「AHOI 2008」逆序对「贪心」

    题意 给定一个长度为\(n\),值域为\([1,k]\),某些位置不确定的数组,求最小的逆序对.\(n\leq 10^4, k \leq 100\) 题解 这题有人用前缀和优化\(dp\)过了,但是这 ...

  2. [AHOI 2008] 聚会

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1832 [算法] 最近公共祖先 [代码] #include<bits/stdc+ ...

  3. 1558:聚会 ybt

    1558:聚会 ybt 题解(看似很难,其实要是摸清了实质这就是个大水题) 上题目 1558:聚会 时间限制: 1000 ms         内存限制: 524288 KB提交数: 82     通 ...

  4. LOJ1036

    AHOI 2008 聚会 Y 岛风景美丽宜人,气候温和,物产丰富.Y 岛上有 N 个城市,有 N-1 条城市间的道路连接着它们.每一条道路都连接某两个城市.幸运的是,小可可通过这些道路可以走遍 Y 岛 ...

  5. How to disable Passwords must meet complexity requirements[windows 7]

    The Password complexity is a Local Policy setting named "Passwords must meet complexity require ...

  6. SQL Server 2008性能故障排查(三)——I/O

    原文:SQL Server 2008性能故障排查(三)--I/O 接着上一章:CPU瓶颈 I/O瓶颈(I/O Bottlenecks): SQLServer的性能严重依赖I/O子系统.除非你的数据库完 ...

  7. HDU1852 Beijing 2008(快速幂+特殊公式)

    As we all know, the next Olympic Games will be held in Beijing in 2008. So the year 2008 seems a lit ...

  8. 在离线环境中发布.NET Core至Windows Server 2008

    在离线环境中发布.NET Core至Windows Server 2008 0x00 写在开始 之前一篇博客中写了在离线环境中使用.NET Core,之后一边学习一边写了一些页面作为测试,现在打算发布 ...

  9. Windows Server 2008 R2常规安全设置及基本安全策略

    这篇文章主要介绍了Windows Web Server 2008 R2服务器简单安全设置,需要的朋友可以参考下 用的腾讯云最早选购的时候悲催的只有Windows Server 2008 R2的系统,原 ...

随机推荐

  1. 【Codeforces 493C】Vasya and Basketball

    [链接] 我是链接,点我呀:) [题意] 题意 [题解] 枚举三分线(离散后)的位置 然后根据预处理的前缀和,快速算出两个队伍的分数. [代码] #include <bits/stdc++.h& ...

  2. String与StringBuffer,StringBuilder

    在java中有3个类来负责字符的操作. 1.Character 是进行单个字符操作的, 2.String 对一串字符进行操作.不可变类. 3.StringBuffer 也是对一串字符进行操作,但是可变 ...

  3. Android BottomSheet:以选取图片为例(2)

     Android BottomSheet:以选取图片为例(2) 附录文章5简单介绍了常见的分享面板在BottomSheet中的具体应用.本文再以常见的选取图片为例写一个例子. 布局文件: < ...

  4. 救命(洛谷 U4525)

    题目背景 XS中学的校长积劳成疾,最终由于无聊而卧病在沙发.需要药(pi)水(gu)拯救他的生活. 题目描述 现在有n种药水,编号分别为1..n,能拯救校长的药水编号为n 每个药水都可以购买到,但有的 ...

  5. Linux下汇编语言学习笔记80 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  6. J - A Bug's Life 并查集

    Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes ...

  7. 洛谷——P1082 同余方程

    P1082 同余方程 题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输 ...

  8. 常见mysql的数据迁移

    1.处理把A表中的部分列复制到B表中主要处理同一库. UPDATE T_EVENT EVE, T_IPMAP MAP SET EVE.c_staff_code = MAP.c_staff_code, ...

  9. How to Use DHCP Relay over LAN? - DrayTek Corp

    Assuming Vigor2960 has two LAN networks. Network Administrator wants that, when the internal DHCP is ...

  10. android学习笔记(9)android程序调试学习

    相应若水老师的第十四课 一,Log日志输出 Log.v(tag,message);        //verbose模式,打印最具体的日志  Log.d(tag,message);        // ...