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个游戏币。

说明

\(100\%\)的数据中,\(N\leq500000\),\(M\leq500000\)

Solution

这题就差在说明里写上“这是一道性质题,推出来性质你就能A,不然就乖乖打暴力吧!”

首先能观察到的是这三个点之间两两的 \(lca\) 只能是两个点或更少

也就是说,必定有至少两对点是同一个 \(lca\)

这启发我们从 \(lca\) 入手推性质。

手玩几组数据发现答案就是三个 \(lca\) 中深度较浅的那个。

所以直接求出这三个 \(lca\) 然后暴力求距离即可

但是正解好像是再推一下式子,发现无论如何 $$ans=dep[x]+dep[y]+dep[z]-dep[lca(x,y)]-dep[lca(x,z)]-dep[lca(y,z)]$$.

求距离都不用,直接减就行了。

#include<cstdio>
#include<cctype>
#define N 500005
#define min(A,B) ((A)<(B)?(A):(B))
#define swap(A,B) ((A)^=(B)^=(A)^=(B)) int dfn[N],top[N],d[N];
int n,m,cnt,tot,sum[N<<2];
int fa[N],sze[N],son[N],head[N]; struct Edge{
int to,nxt;
}edge[N<<1]; void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
} int getint(){
int x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
} void first_dfs(int now){
sze[now]=1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(sze[to])
continue;
fa[to]=now;
d[to]=d[now]+1;
first_dfs(to);
sze[now]+=sze[to];
if(sze[to]>sze[son[now]])
son[now]=to;
}
} void second_dfs(int now,int low){
top[now]=low;
dfn[now]=++tot;
if(son[now])
second_dfs(son[now],low);
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==fa[now] or to==son[now])
continue;
second_dfs(to,to);
}
} int query(int cur,int l,int r,int ql,int qr){
if(ql<=l and r<=qr)
return r-l+1;
int mid=l+r>>1,ans=0;
if(ql<=mid)
ans+=query(cur<<1,l,mid,ql,qr);
if(mid<qr)
ans+=query(cur<<1|1,mid+1,r,ql,qr);
return ans;
} int lca(int x,int y){
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])
swap(x,y);
x=fa[top[x]];
}
if(d[x]<d[y])
swap(x,y);
return y;
} int ask(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])
swap(x,y);
ans+=query(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(d[x]<d[y])
swap(x,y);
if(x!=y)
ans+=query(1,1,n,dfn[y]+1,dfn[x]);
return ans;
} signed main(){
n=getint(),m=getint();
for(int i=1;i<n;i++){
int x=getint(),y=getint();
add(x,y);add(y,x);
}
d[1]=1; first_dfs(1);
second_dfs(1,1);
while(m--){
int a=getint(),b=getint(),c=getint();
int x=lca(a,b),y=lca(a,c),z=lca(b,c);
int ans=d[a]+d[b]+d[c]-d[x]-d[y]-d[z];
if(d[x]>=d[y] and d[x]>=d[z])
printf("%d %d\n",x,ans);
else if(d[y]>=d[x] and d[y]>=d[z])
printf("%d %d\n",y,ans);
else if(d[z]>=d[x] and d[z]>=d[y])
printf("%d %d\n",z,ans);
/*int a=getint(),b=getint(),c=getint();
int x=lca(a,b);
int y=lca(a,c);
if(x!=y){
if(d[x]<d[y]){
int ans=d[a]+d[c]-2*d[y];
ans+=ask(b,y);
printf("%d %d\n",y,ans);
} else{
int ans=d[a]+d[b]-2*d[x];
ans+=ask(c,x);
printf("%d %d\n",x,ans);
}
} else{
int z=lca(b,c);
if(z==x){
int ans=d[a]+d[b]+d[c]-3*d[z];
printf("%d %d\n",z,ans);
} else{
if(d[x]<d[z]){
int ans=d[b]+d[c]-2*d[z];
ans+=ask(a,z);
printf("%d %d\n",z,ans);
} else{
int ans=d[a]+d[b]-2*d[x];
ans+=ask(c,x);
printf("%d %d\n",x,ans);
}
}
}*/
}
return 0;
}

[AHOI2008] 紧急集合的更多相关文章

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

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

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

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

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

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

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

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

  5. [bzoj1787][Ahoi2008]紧急集合

    Description 给定一棵大小为的树,有组询问,每组询问给三个点,求到这三个点距离和最小的点及最小距离和. Input 第一行两个数. 接下来行,每行两个数表示到有一条边. 最后行,每行个数,为 ...

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

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

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

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

  8. BZOJ 1832、1787 洛谷 4281 [AHOI2008]紧急集合

    [题解] 题目要求找到一个集合点,使3个给定的点到这个集合点的距离和最小,输出集合点的编号以及距离. 设三个点为A,B,C:那么我们可以得到Dis=dep[A]+dep[B]+dep[C]-dep[L ...

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

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

随机推荐

  1. jdk8 永久代变更

    java8 去掉了永久代permgen(又称非堆,其实也是堆的一部分),类的方法代码,常亮,方法名,静态变量等存放在永久代中 改为使用元空间 Metaspace , Metaspace 不在是堆的一部 ...

  2. Scrum冲刺阶段2

    成员今日完成的任务 人员 任务 何承华 后端设计 陈宇 后端设计 丁培辉 后端设计 温志铭 主页面的设计 杨宇潇 主页面的设计 张主强 服务器构建 成员遇到的问题 人员 问题 何承华 暂无 陈宇 暂无 ...

  3. MUI 里js动态添加数字输入框后,增加、减少按钮无效

    numbox 的自动初化是在 mui.ready 时完成的mui 页面默认会自动初始化页面中的所有数字输入框,动态构造的 DOM 需要进行手动初始化.比如:您动态创建了一个 ID 为 abc 的数字输 ...

  4. 修改chrome浏览器默认css样式的方法

    最近重新用起了ubuntu kylin,然后又碰到之前让我感到有些难受的一个小问题:用chrome浏览部分网页时,一部分粗体字十分难看,就像是宋体直接加粗那样. 之前就觉得这样看起来很难受,但是找到的 ...

  5. Codeforces Round #512 (Div. 2) D. Vasya and Triangle

    参考了别人的思路:https://blog.csdn.net/qq_41608020/article/details/82827632 http://www.cnblogs.com/qywhy/p/9 ...

  6. Springmvc <mvc:cros>和<mvc:intercepters>同时使用时,跨域被拦截了

    问题原因:cros也是使用拦截器实现的,并且拦截器配置最后一个处理,导致在跨域处理之前调用了业务拦截器 解决方案:推荐使用http://software.dzhuvinov.com/cors-filt ...

  7. 迁移桌面程序到MS Store(5)——.NET Standard

    接下来的几篇,我想讨论下迁移桌面程序到MS Store,可以采用的比较常见.通用性比较强的实施步骤和分层架构. 通常商业项目一般都是不断的迭代,不太可能突然停止更新现有的桌面版本,然后花很长时间从头来 ...

  8. boost::bind 实现原理, 手动实现一个

    template<typename R, typename T, typename A1> class hangj_call { public: hangj_call(R (T::*f_) ...

  9. 教你用python打造WiFiddos

    本文来源于i春秋学院,未经允许严禁转载. 0x00 前言因为在百度上很难找到有关于用python打造WiFidos的工具的,而且不希望大家成为一名脚本小子,所以我打算写一篇,需要的工具有scapy,i ...

  10. Android 从浏览器启动应用

    核心逻辑为AndroidMainfest.xml里面的指定Activity里增加配置: <intent-filter> <data android:scheme="***& ...