LCA【p4281】[AHOI2008]紧急集合 / 聚会
Description
欢乐岛上有个非常好玩的游戏,叫做“紧急集合”。在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要花费一个游戏币。
参加游戏的人三人一组,开始的时候,所有人员均任意分散在各个等待点上(每个点同时允许多个人等待),每个人均带有足够多的游戏币(用于支付使用道路的花费)、地图(标明等待点之间道路连接的情况)以及对话机(用于和同组的成员联系)。当集合号吹响后,每组成员之间迅速联系,了解到自己组所有成员所在的等待点后,迅速在N个等待点中确定一个集结点,组内所有成员将在该集合点集合,集合所用花费最少的组将是游戏的赢家。
小可可和他的朋友邀请你一起参加这个游戏,由你来选择集合点,聪明的你能够完成这个任务,帮助小可可赢得游戏吗?
Input
第一行两个正整数N和M(N<=500000,M<=500000),之间用一个空格隔开。分别表示等待点的个数(等待点也从1到N进行编号)和获奖所需要完成集合的次数。 随后有N-1行,每行用两个正整数A和B,之间用一个空格隔开,表示编号为A和编号为B的等待点之间有一条路。 接着还有M行,每行用三个正整数表示某次集合前小可可、小可可的朋友以及你所在等待点的编号。
Output
一共有M行,每行两个数P,C,用一个空格隔开。其中第i行表示第i次集合点选择在编号为P的等待点,集合总共的花费是C个游戏币。
我天,这题恶心坏了.
话说没出样例就敢交题的我实在是tql。 ~w~
明显到\(LCA\)处就能取到最小的值。
会需要求到\(6\)种(貌似可以求的更少.
首先这六种情况怎么算出来的.
\]
其中\(C_3^2\)代表在三个点中,随便选两个点求\(LCA\)记作\(X\)。
然后再求第三个点与\(X\)的\(LCA\)记作\(Y\)
注意,这里要选择\(X\)作为集合点.这样会更优.
因为走到\(Y\)的话就会是两个点对花费的贡献.这样明显更大啊.
而走到\(X\),这两个点对花费的贡献就会比较小了,另一个人多走就好了.
但是感觉不太对.但又的确是对的 emmm
比如这样:
简单来看的话,我们求出了\(b\)和\(c\)的\(LCA=X\)
\(a\)和\(X\)的\(LCA=Y\)
此时\(a,b,c\)走到\(X\)的价值为\(4\),走到\(Y\)的价值为\(5\)
(这只是一个小栗子啦 qwq)
代码
#include<cstdio>
#include<cctype>
#include<algorithm>
#define R register
#define N 500008
using namespace std;
inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
}
int head[N],tot,depth[N],dis[N];
int n,m,gw[N][21],f[N][21];
struct cod{int u,v;}edge[N<<2];
inline void add(int x,int y,int z)
{
edge[++tot].u=head[x];
edge[tot].v=y;
head[x]=tot;
}
void dfs(int u,int fa)
{
f[u][0]=fa;depth[u]=depth[fa]+1;
dis[u]=dis[fa]+1;
for(R int i=1;(1<<i)<=depth[u];i++)
f[u][i]=f[f[u][i-1]][i-1];
for(R int i=head[u];i;i=edge[i].u)
{
if(edge[i].v==fa)continue;
dfs(edge[i].v,u);
}
}
inline int lca(int x,int y)
{
if(depth[x]>depth[y])swap(x,y);
for(R int i=17;i>=0;i--)
if(depth[x]+(1<<i)<=depth[y])
y=f[y][i];
if(x==y)return y;
for(R int i=17;i>=0;i--)
{
if(f[x][i]==f[y][i])continue;
x=f[x][i],y=f[y][i];
}
return f[x][0];
}
int main()
{
in(n),in(m);
for(R int i=1,x,y;i<n;i++)
in(x),in(y),add(x,y,1),add(y,x,1);
dfs(1,0);
for(R int i=1,x,y,z;i<=m;i++)
{
in(x),in(y),in(z);
R int a=lca(x,y),b=lca(x,z),c=lca(y,z);
R int aa=lca(a,z),bb=lca(y,b),cc=lca(x,c);
R int father,res=214748364;
int ansa=dis[x]+dis[y]-2*dis[a]+dis[a]-2*dis[aa]+dis[z];
int ansb=dis[x]+dis[z]-2*dis[b]+dis[b]-2*dis[bb]+dis[y];
int ansc=dis[y]+dis[z]-2*dis[c]+dis[c]-2*dis[cc]+dis[x];
if(res>ansa)res=ansa,father=a;
if(res>ansb)res=ansb,father=b;
if(res>ansc)res=ansc,father=c;
printf("%d %d\n",father,res);
}
}
LCA【p4281】[AHOI2008]紧急集合 / 聚会的更多相关文章
- P4281 [AHOI2008]紧急集合 / 聚会
P4281 [AHOI2008]紧急集合 / 聚会 lca 题意:求3个点的lca,以及3个点与lca的距离之和. 性质:设点q1,q2,q3 两点之间的lca t1=lca(q1,q2) t2=lc ...
- P4281 [AHOI2008]紧急集合 / 聚会[LCA]
解析 蒟蒻用的办法比较蠢,不如上面的各位大佬,直接化成一个式子了,我还是分类讨论做的. 下面正文. 猜想:最优集合点一定是三点任意两对点对应的路径的交点. 不妨这样想,如果任意两个人经过同一条路径,那 ...
- LUOGU P4281 [AHOI2008]紧急集合 / 聚会 (lca)
传送门 解题思路 可以通过手玩或打表发现,其实要选的点一定是他们三个两两配对后其中一对的$lca$上,那么就直接算出来所有的$lca$,比较大小就行了. #include<iostream> ...
- [AHOI2008]紧急集合 / 聚会(LCA)
[AHOI2008]紧急集合 / 聚会 题目描述 欢乐岛上有个非常好玩的游戏,叫做"紧急集合".在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通 ...
- 【题解】洛谷P4281 [AHOI2008] 紧急集合(求三个点LCA)
洛谷P4281:https://www.luogu.org/problemnew/show/P4281 思路 答案所在的点必定是三个人所在点之间路径上的一点 本蒟蒻一开始的想法是:先求出2个点之间的L ...
- [AHOI2008]紧急集合 / 聚会
题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
- Luogu 4281 [AHOI2008]紧急集合 / 聚会
BZOJ 1832 写起来很放松的题. 首先发现三个点在树上一共只有$3$种形态,大概长这样: 这种情况下显然走到三个点的$lca$最优. 这种情况下走到中间那个点最优. 这种情况下走到$2$最优. ...
- 洛谷 P4281 [AHOI2008] 紧急集合 题解
挺好的一道题,本身不难,就把求两个点的LCA变为求三个点两两求LCA,不重合的点才是最优解.值得一提的是,最后对答案的处理运用差分的思想:假设两点 一点深度为d1,另一点 深度为d2,它们LCA深度为 ...
- 「AHOI2008」「LuoguP4281」紧急集合 / 聚会(LCA
题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...
随机推荐
- js对数组去重的完整版
数组去重是很常见的一个需求,而各种各样的姿势也很多,常见的如indexOf,或者hash,但是他们还是有缺陷,这里我查了一些资料做补充. 一般方式 //一般方法->使用indexOf Array ...
- NOIP2018 集训(二)
A题 神炎皇 问题描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对 \((a,b)\) ,若满足 \(a+b\leq n\) 且 \(a+b\) 是 \(ab\) 的因子,则称 为神 ...
- 孤荷凌寒自学python第四十八天通用同一数据库中复制数据表函数最终完成
孤荷凌寒自学python第四十八天通用同一数据库中复制数据表函数最终完成 (完整学习过程屏幕记录视频地址在文末) 今天继续建构自感觉用起来顺手些的自定义模块和类的代码. 今天经过反复折腾,最终基本上算 ...
- 记一下STL的一个题
A. Diversity time limit per test 1 second memory limit per test 256 megabytes input standard input o ...
- ocrosoft Contest1316 - 信奥编程之路~~~~~第三关 问题 M: 当总统
http://acm.ocrosoft.com/problem.php?cid=1316&pid=12 题目描述 小明想当丑国的总统,丑国大选是按各州的投票结果来确定最终的结果的,如果得到超过 ...
- Ajax---概念介绍
Ajax不是某种编程语言,是一种在无需重新加载整个网页的情况下能够更新部分网页的技术. 运用HTML和CSS来实现页面,表达信息: 运用XMLHttpRequest和Web服务器进行数据的异步交换: ...
- zh-Hans & locales & vs code locale.json
zh-Hans & locales https://code.visualstudio.com/docs/getstarted/locales https://code.visualstudi ...
- 第十四篇:JavaScript
本篇内容 简介 使用 DOM 一. 简介 JavaScript 是世界上最流行的编程语言. 这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. Ja ...
- 【ZBH选讲·模数和】
[问题描述]你是能看到第二题的friends呢.——laekovHja和Yjq在玩游戏,这个游戏中Hja给了Yjq两个数,希望Yjq找到一些非负整数使得这些数的和等于n,并且所有数模maaaaaaaa ...
- DHTMLX 表格组件(dhtmlxGrid )使用介绍
String sql = select {s.*} from t_student s where s.age22; SQLQuery slqQuery = session.createSQLQuery ...