\(\\\)

\(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. RequestMapping_Ant 路径

    [使用@RequestMapping映射请求] [Ant风格资源地址支持3种匹配符] (1)? :匹配文件名中的一个字符. (2) * :匹配文件名中的任意字符. (3) ** :**匹配多层路径. ...

  2. 【Codeforces 382C】Arithmetic Progression

    [链接] 我是链接,点我呀:) [题意] 让你在n个数字中再加入一个数字 使得这n+1个数字排序之后 相邻两个数字的差都相同 [题解] 注意相邻为0的情况 这种情况 只有全都相同才行 只有一种情况 然 ...

  3. [luoguP1282] 多米诺骨牌(DP + 背包)

    传送门 将问题转换成分组背包,每一组有上下两个,每一组中必须选则一个,上面的价值为0,下面的价值为1,求价值最小 因为要求上下两部分差值最小,只需从背包大小为总数 / 2 时往前枚举,找最小答案即可. ...

  4. [luoguP1507] NASA的食物计划(DP)

    传送门 二位费用背包 ——代码 #include <cstdio> #include <iostream> int n, maxv, maxw; ][]; inline int ...

  5. CF576D. Flights for Regular Customers

    n<=150个点,m<=150条路,每条路Ai,Bi,Di表示Ai到Bi有一条有向边,使用他前至少要走Di条路,问1到n最少走几条路. 又是n^4过150的题.... 不同于传统的最短路, ...

  6. 一些非常有用的工具类之javamail(from韩顺平)

    之前编写一个类淘宝服务器时,需要使用javamail发送邮件,搜到的一个工具类,很有用. 需要下载导入:activation.jar和mail.jar package com.cx.service; ...

  7. 【整理】uclibc,eglibc,glibc之间的区别和联系

    http://www.crifan.com/relation_between_uclibc_glibc_eglibc/ 1.Glibc glibc = GNU C Library 是GNU项(GNU ...

  8. android 视频开发2分之1(仿美拍,糗百)

    近期比較忙,非常久没更新博客,今天我们仿一个美拍或者糗事百科的录像功能. 首先确认步奏: 1.打开摄像头: 2.開始录制: 3.支持分段录制,并支持分段删除: 4.把分段录制的视频进行合并: 不说废话 ...

  9. 符号变换引擎(Symbol Transform Engine - STE)

    在写编译器的过程中.我意识到编译事实上是一种符号变换,比方C语言编译成机器码,事实上是C源代码文件里的符号变换成EXE的16进制符号,这和中文翻译成英语的语言翻译器没什么差别. 每一个程序猿都有自己喜 ...

  10. jeewx 微信管家 - 举办商业版本号免费试用活动

    jeewx 微信管家 举办商业版本号免费试用活动 1,关注微信账号:jeecg_scott 2.输入:"jeewx商业版本号试用活动: 你的邮箱(比如:zhangsan@11.com)&qu ...