CS20 D LCA
给出一棵树,许多询问,每次询问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的更多相关文章
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- [bzoj2588][count on a tree] (主席树+lca)
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始 ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- [bzoj3626][LNOI2014]LCA
Description 给出一个$n$个节点的有根树(编号为$0$到$n-1$,根节点为$0$). 一个点的深度定义为这个节点到根的距离$+1$. 设$dep[i]$表示点$i$的深度,$lca(i, ...
- (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[ ...
- bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)
题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...
随机推荐
- BNUOJ 52308 We don't wanna work! set模拟
题目链接: https://acm.bnu.edu.cn/v3/problem_show.php?pid=52308 We don't wanna work! Time Limit: 60000msM ...
- BNUOJ 52303 Floyd-Warshall Lca+bfs最短路
题目链接: https://www.bnuoj.com/v3/problem_show.php?pid=52303 Floyd-Warshall Time Limit: 60000msMemory L ...
- Android笔记-5-EditText密码和Checkbox二选一
EditText密码:明文和密文 密文: public class MainActivity extends Activity { private EditText password = null; ...
- 【搜索】POJ-2718 全排列+暴力
一.题目 Description Given a number of distinct decimal digits, you can form one integer by choosing a n ...
- 10_Java面向对象_第10天(继承、抽象类)_讲义
今日内容介绍 1.继承 2.抽象类 3.综合案例---员工类系列定义 01继承的概述 *A:继承的概念 *a:继承描述的是事物之间的所属关系,通过继承可以使多种事物之间形成一种关系体系 *b:在Jav ...
- CentOS 7.2修改网卡名称
#!/bin/bash #Centos7.2修改网卡名称ens33为eth0 #2017/05/19 if [ -f /etc/sysconfig/grub ];then cd cp /etc/sys ...
- TP5 多入口文件配置的坑
闲话不多说,TP5(5.0.20) 在配置多入口文件的时候你是否遇到过一下的问题呢? 开发设计的需求吧网站拆分为前台.后台.API 3 个模块,对应的也需要3个入口文件,后台和API入口文件是用PAT ...
- app流畅度测试--使用SM
通过测量应用的帧率FPS并不能准确评价App的流畅度,FPS较低并不能代表当前App在UI上界面不流畅,而1s内VSync这个Loop运行了多少次更加能说明当前App的流畅程度. 那么我们可以直接在A ...
- POJ2699_The Maximum Number of Strong Kings
这题目,,,真是...诶.坑了好久. 给一个有向图.U->V表示U可以打败V并得一分. 如果一个人的得分最高,或者他打败所有比自己得分高的人,那么此人就是king. 现在给出每个人的得分,求最多 ...
- UVA10047_The Monocycle
这题....有点奇葩,但是不难. 在矩形方阵里,某人可以往前走或者左拐右拐.都需要消耗一个单位时间. 问某人从一个点走向另一个点的最短时间,并且走过的路程是5的倍数. 由于n,m都小,直接f[n][m ...