[codevs2370]小机房的树<LCA>
题目链接:http://codevs.cn/problem/2370/
这题我还是做了比较久了,因为有人告诉我这是用tarjan离线做
好吧算我是蒟蒻,真心不懂tarjan怎么做,最后还是用倍增做的
所以我也就借着这题复习了一下RMQ了。。
思想就是定义两个数组f[i][j],dis[i][j]分别表示从i上升2^j层到达的节点和需要的价值
然后就是让两个询问节点先在统一深度需要的价值加上到达同一节点需要的价值,没啥难度,看看难度就懂了
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<queue>
#define maxn 50005
using namespace std;
//倍增
int n,m,dis[maxn][],f[maxn][],dep[maxn],head[maxn];
struct edge{
int u,v,w,nxt;
}e[maxn*]; int tot;
void adde(int u,int v,int w){
e[++tot].u=u;
e[tot].v=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot;
} void build(int u)
{
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].v,w=e[i].w;
if(f[v][]==){
f[v][]=u;
dep[v]=dep[u]+;
dis[v][]=w;
build(v);
}
}
} void first(){
for(int j=;j<=;j++){
for(int i=;i<=n;i++){
f[i][j]=f[f[i][j-]][j-];
dis[i][j]=dis[i][j-]+dis[f[i][j-]][j-];
}
}
} int sum=;
int lca(int a,int b){
if(dep[a]<dep[b])swap(a,b);//保证a的深度要深一些
if(dep[a]!=dep[b]){//让不同深度到相同深度
int d=dep[a]-dep[b];
for(int i=;d;i++){
if(d&){
sum+=dis[a][i];
a=f[a][i];
}
d=d>>;//这里是经典的类似二进制的方法分解成2^i1+2^i2+……
}
}
if(a==b)return sum;
for(int i=;i>=;i--){
if(f[a][i]!=f[b][i]){//两个人刚刚好达不到根节点
//这样的意义就是不断的缩小向上扩展的深度,可以到达终点
//因为是不等于才执行,所以循环完了肯定还是到不了
sum+=dis[a][i]+dis[b][i];
a=f[a][i];b=f[b][i];
}
}
sum+=dis[a][]+dis[b][];//2^i=2^i-1+2^i-2+2^1+2^0+2^0
return sum; } int main(){
memset(head,-,sizeof(head));
scanf("%d",&n);
for(int i=;i<n;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
adde(u+,v+,w);adde(v+,u+,w);
}
f[][]=;//倍增过界了就默认为到了根节点
build();
first();
scanf("%d",&m);
for(int i=;i<=m;i++)
{
int a,b;sum=;
scanf("%d%d",&a,&b);
int ans=lca(a+,b+);
printf("%d\n",ans);
}
}
[codevs2370]小机房的树<LCA>的更多相关文章
- codevs2370 小机房的树 x
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号 ...
- [CodeVS2370] 小机房的树 (LCA, 树链剖分, LCT)
Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花 ...
- codevs2370 小机房的树
题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子, ...
- 【codevs2370】小机房的树 LCA 倍增
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0 ...
- 小机房的树 codevs 2370
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 小机房有棵焕狗种的树 ...
- Codevs 2370 小机房的树
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为 ...
- CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先)
CodeVs.2370 小机房的树 ( LCA 倍增 最近公共祖先) 题意分析 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天, ...
- LCA(倍增在线算法) codevs 2370 小机房的树
codevs 2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description 小机房有棵焕狗种的树,树上有N个节点, ...
- codevs——2370 小机房的树
2370 小机房的树 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 小机房有棵焕狗种的树,树上有N个 ...
随机推荐
- 怎么用Python写一个三体的气候模拟程序
首先声明一下,这个所谓的三体气候模拟程序还是很简单的,没有真的3D效果或数学模型之类的,只不过是一个文字表示的模拟程序.该程序的某些地方可能不太严谨,所以也请各位多多包涵. 所谓三体气候模拟,就是将太 ...
- 用table类型布局一个新闻网页
<html><head><meta http-equiv="Content-Type" content="text/html; charse ...
- 对JS中事件委托的理解
什么是事件委托: 事件委托——给父元素绑定事件,用来监听子元素的冒泡事件,并找到是哪个子元素的事件.(不理解冒泡的可以去百度下) 定义:利用事件冒泡处理动态元素事件绑定的方法,专业术语叫事件委托. 使 ...
- JavaScript判断一个对象是否为空
本文介绍了判断一个对象是否为空的几种方法 测试用例 test1 = 1; test2 = {}; test3 = {a:1,b:2} 1. 判断Object.keys()的长度 function _i ...
- git涨姿势(一)
今天遇到了一个git冲突问题,解决冲突方案我是当然知道的,就是本地不知道何时自己傻不拉几的新建了一个relese分支,而remote是没有release分支的,需要拉取的是release/V1.4.2 ...
- 最简单易懂的实现CRC16校验
public String getCRC16(byte[] bytes) { //CRC寄存器全为1 int CRC = 0x0000ffff; //多项式校验值 int POLYNOMIAL = 0 ...
- 如何在国内离线安装Chrome扩展并科学查资料
国内离线安装Chrome扩展 这些链接是从知乎国内离线安装 Chrome 扩展程序的方法总结 - 知乎看到的, 怕这个链接失效, 在这里自己备一份: Crx4Chrome - Download CRX ...
- rimraf node_modules 突然不能用了 怀疑是yarn的问题,从环境变量将yarn删掉,能用了
rimraf node_modules 突然不能用了 怀疑是yarn的问题,从环境变量将yarn删掉,能用了
- 一步一步学习S-MSCKF(一)连续时间IMU误差状态运动模型
1 IMU真实状态运动模型 状态向量: \(x_{I}=\left[{{_{G}^{I}{q(t)}}^{T},{b_{g}(t)}^{T},{^{G}v_{I}(t)}^{T},{b_{a}(t)} ...
- 使用Servlet和JSp在浏览器上实现对数据库表的增删改查(新手)
第一步:用户输入网址进入一个登陆界面. 里面要有账号密码输入. 登陆界面链接到登陆的Servlet类中. Servlet类 --> 1.接收参数(账户密码) 2.调用DAO层的 SQL语句 验 ...