P10952 聚会 题解
题目链接
题目大意
对于一棵树,求出一个点对于给定的三个点(以下简称 $x$,$y$,$z$ 且可以重复)距离最短。
题解
对于点的距离,不难想到 LCA 处理。而对于本题,则有两种情况。
第一问
三点中有一为另外两个点的祖先时,所求目标点(以下简称 $v$ )的深度(简称 $d_v$ )一定在三点深度之间。
三点共同 LCA 为另一点时,$v$ 即为三点的 LCA 。
这两种情况包含了所有形式,所以我们可以通过求出 $\operatorname {LCA(x,y)}$,$\operatorname {LCA(x,z)}$,$\operatorname {LCA(y,z)}$ 后选取最深的点,即所求的 $v$。对于此结论,第二种情况自然不用多说,而第一种情况中显然 $d_x \le d_v \le d_y$($d_x \le d_y \le d_z$),最深的点可以使 $y$ 与 $z$ 到 $v$ 的距离最短,即 $y$ 与 $z$ 不会走相同的边。
第二问
设点 $x$ 到根节点的距离为 $dis_x$,由树的性质得答案为 $dis_x+dis_y+dis_z-dis_{\operatorname{LCA(x,y)}}-dis_{\operatorname{LCA(x,z)}}-dis_{\operatorname{LCA(y,z)}}$。
代码
#include <bits/stdc++.h>
using namespace std;
#define mst(x, y) memset(x, y, sizeof(x))
#define pp pair<int, int>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y)
int read(){int x = 0, f = 1;char c = getchar();while(c < '0' || c > '9'){if(c == '-') f = -1;c = getchar();}while(c >= '0' && c <= '9'){x = 10*x+c-'0';c = getchar();}return f*x;}
void write(int x){if(x < 0){putchar('-');x = -x;}if(x > 9) write(x/10);putchar(x%10 | 0x30);return;}
const int N = 1000005, inf = 0x3f3f3f3f;
int n, q, hd[N], ver[N], nxt[N], idx, d[N], f[N][25], ans, mk[N];
void add(int x, int y){
nxt[++idx] = hd[x];
ver[idx] = y;
hd[x] = idx;
}
void bfs(){
queue <int> q;
q.push(1);
mk[1] = 1, d[1] = 1;
while(q.size()){
int t = q.front();
q.pop();
for(int i = hd[t];i;i = nxt[i]){
int y = ver[i];
if(mk[y]) continue;
mk[y] = 1;
d[y] = d[t]+1, f[y][0] = t;
for(int j = 1;j <= 20;j++){
f[y][j] = f[f[y][j-1]][j-1];
}
q.push(y);
}
}
}
int lca(int x, int y){
if(d[x] < d[y]) swap(x, y);
for(int i = 20;i >= 0;i--){
if(d[f[x][i]] >= d[y]) x = f[x][i];
}
if(x == y) return x;
for(int i = 20;i >= 0;i--){
if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
}
return f[x][0];
}
void init(){
n = read(), q = read();
for(int i = 1;i < n;i++){
int x = read(),y = read();
add(x, y);add(y, x);
}
bfs();
}
void solve(){
while(q--){
int x = read(), y = read(), z = read();
int l1 = lca(x, y), l2 = lca(y, z), l3 = lca(x, z);
ans = d[x]+d[y]+d[z]-d[l1]-d[l2]-d[l3];
if(d[l1] >= d[l2] && d[l1] >= d[l3]){
write(l1);putchar(' ');write(ans);puts("");
}
else if(d[l2] >= d[l1] && d[l2] >= d[l3]){
write(l2);putchar(' ');write(ans);puts("");
}
else if(d[l3] >= d[l2] && d[l3] >= d[l1]){
write(l3);putchar(' ');write(ans);puts("");
}
}
}
int main(){
init();
solve();
return 0;
}
另外不要忘了双倍经验。
P10952 聚会 题解的更多相关文章
- toj 4602 松鼠聚会
题目: 草原上住着一群小松鼠,每个小松鼠都有一个家.时间长了,大家觉得应该聚一聚.但是草原非常大,松鼠们都很头疼应该在谁家聚会才最合理. 每个小松鼠的家可以用一个点x,y表示,两个点的距离定义为:点( ...
- 【题解】Luogu P5361 [SDOI2019]热闹又尴尬的聚会
原题传送门 构造题. 明显p,q都越大越好 我们考虑每次取出度最小的点,加到尴尬聚会的集合中(因为把与它相邻的点全删了,不珂能出现认识的情况),把它自己和与自己相连的点从图上删掉(边也删掉),记下这个 ...
- 题解 BZOJ 1037 & Luogu P2592 [ZJOI2008]生日聚会
BZOJ & Luogu 老师说是背包?并没看出来QAQ 设f[i][j][o][p]表示已经选了i个人,j个男生,男生比女生最多多o个,女生比男生最多多p个时的方案数 两种转移: <= ...
- 题解 [BZOJ1832][AHOI2008] 聚会
题面 解析 首先对于其中的两个点\(x,y\)最近的点显然就是他们的\(lca\)(我们把它设为\(p1\)), 然后考虑第三个点\(z\)与\(p1\)的\(lca,p2\). 有以下几种情况: \ ...
- 【简】题解 AWSL090429 【聚会】
这题直接换根dp 记录在要转移的点的子树中有多少牛 #include<bits/stdc++.h> using namespace std; #define ll long long #d ...
- 暑假训练round 3 题解
今天做题运气出奇的好,除了几处小错误调试之后忘记改掉了……最后还AK了……虽然题目不难,学长也说是福利局,但是对个人的鼓励作用还是挺大的……至此暑假训练就结束了,也算没有遗憾……. 题解如下: Pro ...
- BZOJ3170: [Tjoi 2013]松鼠聚会
3170: [Tjoi 2013]松鼠聚会 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 531 Solved: 249[Submit][Statu ...
- BZOJ 3170: [Tjoi 2013]松鼠聚会 切比雪夫距离
3170: [Tjoi 2013]松鼠聚会 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...
- tyvj1161聚会的名单(trie树)
背景 Background 明天就是candy的生日,candy又会邀请自己的一大堆好友来聚会了!哎!又要累坏飘飘乎居士了!! 描述 Description 明天就是candy的生日.晚上,c ...
- [bzoj\lydsy\大视野在线测评]题解(持续更新)
目录: 一.DP 二.图论 1.最短路 2.强连通分量 三.利用单调性维护 四.贪心 五.数据结构 1.并查集 六.数学 1.计数问题 2.数学分析 七.博弈 八.搜索 /////////////// ...
随机推荐
- js 中必须加分号的位置集合
1. 匿名函数(自执行函数)(function (){}()) 2. 解析赋值 2 个变量交换位置
- 常用的linux命令 docker常用命令
mkdir 新建目录 rmdir 删除目录 rm只能删除文件,不能删除目录 cp test.txt Documents 进入容器的目录 docker exec -it <container_id ...
- 初学者浅析C++类与对象
C++类与对象 class class基本语法 class ClassName { public: // 公有成员 Type memberVariable; // 数据成员 ReturnType me ...
- vue之JavaScript封装
导入js文件有很多种方式,我喜欢使用这种,感觉跟框架导入很相似.没有多余的沉湎. 定义一个js文件,比如util.js import Vue from "vue"; //===== ...
- AI年代,谁还用难用的Keil?快快换CLion!!! 破解+环境替换 [下]
keil环境的替代 1.首先 我这里大体框架引入大佬稚晖君的博客: https://www.bilibili.com/read/cv6308000/ 如果有需要配置标准库的可以参考这里: https: ...
- C++面经(持续更新)
一. c,c++区别<九大点> c: 面向过程 c++: 面向对象(封装,继承,多态) 对象:对数据和作用于数据的操作组成的封装实体 类:描叙了一组有相同属性和方法的对象<虚拟> ...
- UE4纯C++实现游戏快捷栏之物品读取
我们在上一步骤中创建了快捷栏的UI界面,在这一部分我们将从Json文件中读取物品的相关信息(种类以及属性),来填充到游戏数据中进行存储以便快捷栏使用,具体分以下几部分完成. 1.Types.h: 添加 ...
- RK3568,字符设备框架:管理同主设备号、不同次设备号设备
字符设备框架:管理同主设备号.不同次设备号设备 以下代码针对迅为开发板RK3568,开发板系统是ubuntu20.04, 正文 以下是我写的字符设备框架,实现了管理同主设备号.不同次设备号的功能. 代 ...
- OpenWRT/iStoreOS 不从头编译内核安装4G LTE网卡 Quectel EM05-CE记录
我的机器是x86装了iStoreOS,有4G网卡Quectel EM05 https://www.quectel.com/cn/product/lte-em05 主要参考资料如下 https://ww ...
- XSS跨站脚本之portswigger labs练习
目录 1 什么是XSS 2 XSS的类型有哪些 3 XSS攻击的过程和原理 4 XSS的防御 5 可能会用到的XSS Payload资源 6 靶场训练 portswigger labs 6.1 没有任 ...