牛客小白月赛13 小A的最短路(lca+RMQ)
链接:https://ac.nowcoder.com/acm/contest/549/F
来源:牛客网
题目描述
输入描述:
第一行一个整数N代表景区的个数。
接下来N-1行每行两个整数u,v代表从位置u到v之间有一条路径可以互相到达。
接下来的一行两个整数U,V表示这两个城市之间可以直接坐缆车到达。
接下来一行一个整数Q,表示有Q次询问。
接下来的Q行每行两个整数x,y,代表小A的位置在x,而他想要去的地方是y。
输出描述:
对于每个询问下x,y输出一个结果,代表x到y消耗的最少体力对于每个询问下x,y输出一个结果,代表x到y消耗的最少体力
输入
4
1 2
1 3
2 4
3 4
2
1 3
3 4
输出
1
0 解题思路:很明显是lca的板子题,唯一不同的就是加了一条权值为零的边而已,我们假设边x-y权值为零,需要求u-v的最小距离,dis【i,j】为i到j的最小距离,此时u-v的最小距离为min(dis【u,v】,min(dis【u,x】+dis【y,v】,dis【u,y】+dis【x,v】))了。
在这,我就简单讲一下lca的RMQ的求法吧。
两个结点的最近公共祖先的求法:
就如上面的一棵树,我们按DFS遍历一遍,把遍历到的结点加入到某个数组中可以得到一个序列:1 2 4 2 5 7 9 7 5 8 5 2 1 3 6 3 1
他们的深度依次为: 0 1 2 1 2 3 4 3 2 3 2 1 0 1 2 1 0
要查找某两个结点的最近公共祖先,即查找这这个序列中两个结点所对应的这一段的深度最小的那个结点。比如查找5和6的最近公共祖先,他们对应的结点序列为:
5 7 9 7 5 8 5 2 1 3 6,深度为
2 3 4 3 2 3 2 1 0 1 2,深度最小为1结点(深度为0)。这里可以使用RMQ来维护(当然也可以用线段树),不熟悉RMQ的可以看:传送门。(感觉讲的很渣啊。。。)
当然,求lca的还有别的方法,等以后有机会再更新吧(目前不会QAQ)。
这里贴上本题的AC代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ri register int
typedef long long ll; inline ll gcd(ll i,ll j){
return j==?i:gcd(j,i%j);
}
inline ll lcm(ll i,ll j){
return i/gcd(i,j)*j;
}
inline void read(int &x){
char ch=x=;
int f=;
while(!isdigit(ch)){
ch=getchar();
if(ch=='-'){
f=-;
}
}
while(isdigit(ch))
x=x*+ch-'',ch=getchar();
x=x*f;
}
const int maxn=3e5+;
struct st1{
int to,w;
st1():to(),w(){
}
st1(int to,int w):to(to),w(w){
}
};
vector<st1> vec[maxn];
int dep[maxn];
int in[maxn*];//某个点在欧拉序第一次出现的位置
int co;
int vis[maxn];
int st[maxn*][];//存运行dfs时候的序列(好像叫欧拉序)
void dfs(int u,int cnt){
vis[u]=;
st[++co][]=u;
in[u]=co;
dep[u]=cnt;
for(int i=;i<vec[u].size();i++){
st1 tem=vec[u][i];
if(vis[tem.to]==){
dfs(tem.to,cnt+);
st[++co][]=u;
}
}
}
void getst(){
for(int i=;(<<i)<=co;i++){
for(int be=;be+(<<i)-<=co;be++){
if(dep[st[be][i-]]<dep[st[be+(<<(i-))][i-]]){
st[be][i]=st[be][i-];
}
else{
st[be][i]=st[be+(<<(i-))][i-];
}
}
}
}
int rmq(int l,int r){
int x=in[l];
int y=in[r];
if(x>y)swap(x,y);
int tem=floor(log(y-x+)/log());
int tem1=st[x][tem];
int tem2=st[y-(<<tem)+][tem];
if(dep[tem1]<dep[tem2])return tem1;
else return tem2;
}
int main(){
int n;
int u,v;
co=;
read(n);
for(int i=;i<n;i++){
read(u);read(v);
vec[u].push_back(st1(v,));
vec[v].push_back(st1(u,));
}
read(u);read(v);
int k;
dfs(,);
getst();
scanf("%d",&k);
int x,y;
for(int i=;i<k;i++){
read(x);read(y);
int ans;
ans=dep[x]+dep[y]-*dep[rmq(x,y)];
ans=min(ans,dep[x]+dep[u]-*dep[rmq(x,u)]+dep[y]+dep[v]-*dep[rmq(y,v)]);
ans=min(ans,dep[x]+dep[u]-*dep[rmq(y,u)]+dep[y]+dep[v]-*dep[rmq(x,v)]);
printf("%d\n",ans);
}
return ;
}
牛客小白月赛13 小A的最短路(lca+RMQ)的更多相关文章
- 牛客小白月赛13 小A的回文串(Manacher)
链接:https://ac.nowcoder.com/acm/contest/549/B来源:牛客网 题目描述 小A非常喜欢回文串,当然我们都知道回文串这种情况是非常特殊的.所以小A只想知道给定的一个 ...
- 牛客小白月赛13 小A买彩票 (记忆化搜索)
链接:https://ac.nowcoder.com/acm/contest/549/C来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- 牛客小白月赛13 小A的柱状图(单调栈)
链接:https://ac.nowcoder.com/acm/contest/549/H来源:牛客网 题目描述 柱状图是有一些宽度相等的矩形下端对齐以后横向排列的图形,但是小A的柱状图却不是一个规范的 ...
- 单调栈+前缀和 || Nowcoder || 牛客小白月赛13 || 小A的柱状图
题面:小A的柱状图 题解:无 代码: #include<cstdio> #include<cstring> #include<iostream> #define l ...
- 牛客小白月赛13-J小A的数学题 (莫比乌斯反演)
链接:https://ac.nowcoder.com/acm/contest/549/J来源:牛客网 题目描述 小A最近开始研究数论题了,这一次他随手写出来一个式子,∑ni=1∑mj=1gcd(i,j ...
- 牛客小白月赛6 I 公交线路 最短路 模板题
链接:https://www.nowcoder.com/acm/contest/136/I来源:牛客网 题目描述 P市有n个公交站,之间连接着m条道路.P市计划新开设一条公交线路,该线路从城市的东站( ...
- 牛客小白月赛13 G(双向搜索)
AC通道 两边同步搜,一步里面A走一次B走两次,遇到对方走过的地方就得到了答案. #include <bits/stdc++.h> using namespace std; const i ...
- 牛客小白月赛13 E(图、矩阵幂)
AC通道 如果建立第一天某点到某点有几条路的矩阵,做k次矩阵乘就是第k天某点到某点有几条路.统计即可. #include <bits/stdc++.h> using namespace s ...
- 【牛客小白月赛21】NC201605 Bits
[牛客小白月赛21]NC201605 Bits 题目链接 题目描述 Nancy喜欢做游戏! 汉诺塔是一个神奇的游戏,神奇在哪里呢? 给出3根柱子,最开始时n个盘子按照大小被置于最左的柱子. 如果盘子数 ...
随机推荐
- submit提交判断
body部分 <form action='https://www.baidu.com' method='post' > 用 户 名:<input ...
- 使用Navicat连接阿里云mysql报错10061
1.添加一个远程访问账号admin mysql> use mysql; mysql> GRANT ALL ON *.* TO 账户@'%' IDENTIFIED BY '密码' WITH ...
- New Journey Prepare
1. 车载USB充电器. 2. 轮胎检测,备胎充气. 3. 给刹车片加润滑油. 3. 给娃办身份证. 4. 取公积金. 5. 入职准备材料.
- 反射 内省 BeanUtil 综合使用
package com.zsphp.domain; public class User { private String userId; private String userName; privat ...
- ie浏览器许多图片放在一起会有间隙
解决方法一(推荐):设置图片父元素font-size:0. 解决方法二:设置图片为float:并且图片设为块级元素.
- [python,2019-02-15] 最短回文串
给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串.找到并返回可以用这种方式转换的最短回文串. 示例 1: 输入: "aacecaaa" 输出: "aaa ...
- calc()使用用法
calc()是css3的一个新增的功能,用来指定元素的长度. 它是动态设置元素值,可由加减乘除算法得到最后计算值. 比如说“width:calc(50% + 5em)” 在使用less解析中calc运 ...
- matlab-双摆仿真
在物理学和数学中,在动力系统领域,双摆是一个摆锤,另一个摆锤连接在其末端,是一个简单的物理系统,具有丰富的动态特性,对初始条件具有很强的敏感性.双摆的运动由一组耦合的常微分方程控制并且是混沌的. 由于 ...
- Unable to compile class for JSP 的可能原因
浏览器访问web jsp文件,导致500-Unable to compile class for JSP 的原因. 原因一:查看网上的方法,说很可能的原因是tomcat版本比JDK的版本要低导致的.所 ...
- 稀疏矩阵 part 5
▶ 目前为止能跑的所有代码及其结果(2019年2月24日),之后添加:DIA 乘法 GPU 版:其他维度的乘法(矩阵乘矩阵):其他稀疏矩阵格式之间的相互转化 #include <stdio.h& ...