给出一棵树,许多询问,每次询问A,B,C三点,求一点使到三点距离最小,输出该点和最小值。

很明显就是求LCA,三种组合都求一次LCA,然后在里面选个距离和最小的就行了。

官方题解里面的代码求LCA是在线DFS RMQ的方法..先记录欧拉序,且记录某个点在序列里的第一个位置,每次询问a,b的LCA就是询问两者在欧拉序列里第一个位置之差中的那些点里面深度最小的

LCA(a,b)=RMQ(dep, pos[a], pos[b])

/** @Date    : 2017-09-27 20:41:28
* @FileName: CS20 C LCA RMQ.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8; int dep[N];
int pos[N];
int rmq[19][2*N];
int eul[2*N], c, l[2*N]; vector<int> edg[N]; void dfs(int x, int pre)
{
eul[++c] = x;
pos[x] = c;
if(pre) dep[x] = dep[pre] + 1;
for(auto i: edg[x])
{
if(i == pre)
continue;
dfs(i, x);
eul[++c] = x;
}
} void init()
{
dfs(1, 0);
for(int i = 2; i <= c; i++)//预处理 2^k=x对应的k
l[i] = l[i / 2] + 1;
for(int i = 1; i <= c; i++)
rmq[0][i] = eul[i];
for(int j = 1; (1 << j) <= c; j++)
for(int i = 1; i <= c; i++)
{
rmq[j][i] = rmq[j - 1][i];
if(i + (1 << (j - 1)) > c)
continue;
if(dep[rmq[j - 1][i + (1 << (j - 1))]] < dep[rmq[j][i]])
rmq[j][i] = rmq[j - 1][i + (1 << (j - 1))];
}
} int lca(int x, int y)
{
if(pos[x] > pos[y])
swap(x, y);
int dis = pos[y] - pos[x] + 1;
int k = l[dis];
if(dep[rmq[k][pos[x] + dis - (1 << k)]]
< dep[rmq[k][pos[x]]])
return rmq[k][pos[x] + dis - (1 << k)];
else return rmq[k][pos[x]];
} int distance(int a, int b)
{
int ac = lca(a, b);
return dep[a] + dep[b] - 2 * dep[ac];
}
int main()
{
int n, q;
cin >> n >> q;
for(int i = 0; i < n - 1; i++)
{
int x, y;
scanf("%d%d", &x, &y);
edg[x].PB(y);
edg[y].PB(x);
}
init();
while(q--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int ac1 = lca(a, b);
int ac2 = lca(a, c);
int ac3 = lca(b, c);
int ans1 = distance(ac1, a) + distance(ac1, b) + distance(ac1, c);
int ans2 = distance(ac2, a) + distance(ac2, b) + distance(ac2, c);
int ans3 = distance(ac3, a) + distance(ac3, b) + distance(ac3, c);
if(ans1 > ans2)
swap(ans1, ans2), swap(ac1, ac2);
if(ans1 > ans3)
swap(ans1, ans3), swap(ac1, ac3);
printf("%d %d\n", ac1, ans1);
}
return 0;
}

CS20 D LCA的更多相关文章

  1. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  2. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  3. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  4. [bzoj2588][count on a tree] (主席树+lca)

    Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...

  5. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  6. poj3417 LCA + 树形dp

    Network Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4478   Accepted: 1292 Descripti ...

  7. [bzoj3626][LNOI2014]LCA

    Description 给出一个$n$个节点的有根树(编号为$0$到$n-1$,根节点为$0$). 一个点的深度定义为这个节点到根的距离$+1$. 设$dep[i]$表示点$i$的深度,$lca(i, ...

  8. (RMQ版)LCA注意要点

    inline int lca(int x,int y){ if(x>y) swap(x,y); ]][x]]<h[rmq[log[y-x+]][y-near[y-x+]+]])? rmq[ ...

  9. bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)

    题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...

随机推荐

  1. <s:action>的一些用法

    Action标签,顾名思义,是用来调用Action的标签,在JSP中页面中,可以具体指定某一命名空间中的某一Action.而标签的主体用于显示及渲染Actionr的处理结果. action标签有如下几 ...

  2. windows下的C++ socket服务器(3)

    int make_server_socket(int port) { WSADATA inet_WsaData; WSAStartup(MAKEWORD(), &inet_WsaData); ...

  3. 总结MySQL修改最大连接数的两个方式

    最大连接数是可以通过mysql进行修改的,mysql数据库修改最大连接数常用有两种方法,今天我们分析一下这两种方法之间的特点和区别,以便我们能更好的去维护mysql.下面我们来看一下mysql修改最大 ...

  4. Linux限制cpu睿频&限制频率

    .关闭睿频 > /sys/devices/system/cpu/intel_pstate/no_turbo .限制CPU最大频率到50% " | sudo tee /sys/devic ...

  5. apache +PHP多版本 切换的问题

    在开发中切换php版本的时候出错 经过2小时的日子排查终于找到是因为切换版本后加载的php7ts.dll模块还是原来版本的,因此保pid file 错误 解决方法 PHPIniDir "H: ...

  6. [转帖]CentOS基础命令大全

    https://www.toutiao.com/i6601298434651587085/ 1.关机 (系统的关机.重启以及登出 ) 的命令 shutdown -h now 关闭系统(1) init ...

  7. js & click copy to clipboard

    js & click copy to clipboard https://www.cnblogs.com/xgqfrms/p/9999061.html https://www.cnblogs. ...

  8. poj3061 Subsequence(尺取)

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  9. [Ispc2009]Let there be rainbows!

    Description HY Star是一个处处充满和谐,人民安居乐业的星球,但是HYStar却没有被评上宇宙文明星球,很大程度上是因为星球的形象问题. HY Star由N个国家组成,并且在一些国家之 ...

  10. NOI2010~NOI2018选做

    [NOI2010] [NOI2010]海拔 高度只需要0/1,所以一个合法方案就是一个割,平面图求最小割. [NOI2010]航空管制 反序拓扑排序,每次取出第一类限制最大的放置,这样做答案不会更劣. ...