HDU2586 How far away ?
一、描述
很久没写代码了,在之前一直在参与准备ASC比赛和美赛,现在又重新捡起来。目标是两个月后的邀请赛。
这题是树链拋分解决LCA问题的一个模板题。
首先介绍下树链拋分的基本思想。
- 对于任意一颗树,定义重链为自上走到下,经历的节点数量最多的一条路径。定义轻链为其他链。
- 每个节点都属于一个重链。如果节点本身不在父节点所在的重链上,那么说他一定是一条新的重链的顶端。
- 对于任意节点,采取每次都直接跳到重链顶端的方式,最多logn次可以跳到树根。(下述循环最多执行LOGN)
while(now!=root)
{
if(now==top[now])now=father[now];
now=top[now];
} 对于每两个不同的节点,最多跳LOGN次可以使得两个节点走到同一条重链上,在跳跃的时候进行分级跳跃,即定义重链的级别(在祖先节点所经历的重链的条数)。于是跳跃函数如下:
ll query(ll a,ll b)
{
ll ret=;
while(top[a]!=top[b])
{
if(depth[a]<depth[b])
{
jump(b,ret);
}else jump(a,ret);
}
ret+=abs(top_dis[a]-top_dis[b]);
return ret;
}
#include<bits/stdc++.h>
using namespace std; #define ll long long
#define pp pair <ll,ll>
#define veci vector<ll>
#define vecp vector<pp> const ll MAXN=; ll depth[MAXN];
ll fa[MAXN];
ll dis[MAXN];
ll top_dis[MAXN];
ll child[MAXN];
ll top[MAXN];
vecp path[MAXN]; ll n,m; void dfs(ll now,ll father)
{
fa[now]=father;
child[now]=;
ll len=path[now].size();
for(ll i=;i<len;++i)
{
ll tar=path[now][i].first;
ll val=path[now][i].second;
if(tar==father)continue;
dis[tar]=val;
dfs(tar,now);
child[now]+=child[tar];
}
child[now]++;
} void build_tree(ll now,ll to,ll dep,ll length)
{
top[now]=to;
depth[now]=dep;
top_dis[now]=length;
ll len=path[now].size(); ll maxx=;
ll node=;
for(ll i=;i<len;++i)
{
ll tar=path[now][i].first;
ll val=path[now][i].second;
if(tar==fa[now])continue;
node = maxx < child[tar] ? i : node;
maxx=max(maxx,child[tar]);
}
for(ll i=;i<len;++i)
{
ll tar=path[now][i].first;
ll val=path[now][i].second;
if(tar==fa[now])continue;
if(i==node) build_tree(tar,to,dep,length+val);
else build_tree(tar,tar,dep+,);
}
} ll jump(ll &now,ll &ret)
{
ret+=top_dis[now];
now=top[now];
ret+=dis[now];
now=fa[now];
return now;
} ll query(ll a,ll b)
{
ll ret=;
while(top[a]!=top[b])
{
if(depth[a]<depth[b]) jump(b,ret);
else jump(a,ret);
}
ret+=abs(top_dis[a]-top_dis[b]);
return ret;
} void init()
{
cin>>n>>m;
for(ll i=;i<=n;++i)path[i].clear();
for(ll i=;i<n;++i)
{
ll a,b,c;
cin>>a>>b>>c;
path[a].push_back(make_pair(b,c));
path[b].push_back(make_pair(a,c));
}
dfs(,);
build_tree(,,,);
for(ll i=;i<m;++i)
{
ll a,b;cin>>a>>b;
cout<<query(a,b)<<"\n";
} } int main()
{
cin.sync_with_stdio(false);
ll t;
cin>>t;
for(ll i=;i<t;++i)init(); return ;
}
HDU2586 How far away ?的更多相关文章
- hdu-2586 How far away ?(lca+bfs+dfs+线段树)
题目链接: How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- HDU2586 How far away ?(LCA模板题)
题目链接:传送门 题意: 给定一棵树,求两个点之间的距离. 分析: LCA 的模板题目 ans = dis[u]+dis[v] - 2*dis[lca(u,v)]; 在线算法:详细解说 传送门 代码例 ...
- HDU2586 How far away ? 邻接表+DFS
题目大意:n个房子,m次询问.接下来给出n-1行数据,每行数据有u,v,w三个数,代表u到v的距离为w(双向),值得注意的是所修建的道路不会经过一座房子超过一次.m次询问,每次询问给出u,v求u,v之 ...
- HDU2586.How far away ?——近期公共祖先(离线Tarjan)
http://acm.hdu.edu.cn/showproblem.php?pid=2586 给定一棵带权有根树,对于m个查询(u,v),求得u到v之间的最短距离 那么仅仅要求得LCA(u,v),di ...
- hdu2586 How far away ?(lca模版题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树还有两个点然后求这两个点的最短距离. 题解:val[a]+val[b]-2*va ...
- HDU2586 How far away ? (树链剖分求LCA)
用树链剖分求LCA的模板: 1 #include<iostream> 2 #include<algorithm> 3 using namespace std; 4 const ...
- LCA在线算法(hdu2586)
hdu2586 How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 2586.How far away ?-离线LCA(Tarjan)
2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...
- LCA(最近公共祖先)——Tarjan
什么是最近公共祖先? 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先,就是两个节点在这棵树上深度最大的公共的祖先节点. 换句话说,就是两个点在这棵树上距离最近的公共祖先节点. ...
随机推荐
- 冷笑话,idea 按删除键就是undo?
第一反应是keymap被改了,一看 那么,看起来就是alt出问题了 解决方法 在公司换一个键盘或者狂按alt
- 使用Pycharm开发python下django框架项目生成的文件解释
目录MyDjangoProject下表示工程的全局配置,分别为setttings.py.urls.py和wsgi.py,1.其中setttings.py包括了系统的数据库配置.应用配置和其他配置,2. ...
- Spring cloud Eureka 服务治理(注册服务提供者)
搭建完成服务注册中心,下一步可以创建服务提供者并向注册中心注册服务. 接下来我们创建Spring Boot 应用将其加入Eureka服务治理体系中去. 直接使用签名章节创建hello服务项目改造: 1 ...
- Centos6.8 Mysql5.6 安装配置教程
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品.MySQL 最流行的关系型数据库管理系统,在 WEB 应用方面MySQL是最好的 RDBMS ...
- 12个非常不错的javascript类库
Javascript是一个解释性的编程语言.最初作为浏览器的一部份在浏览器中运行,可以和用户交互,并且控制浏览器,异步通讯,修改显示的document.在这篇文章中,我们收集了12款最新的Javasc ...
- 【来龙去脉系列】QRCode二维码的生成细节和原理
二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型:比如:字符,数字, ...
- Shell脚本 - 用来检查memcache并自动重启生效脚本
#!/bin/sh#check memcache process and restart if downmm_bin="/usr/local/bin/memcached"mm_lo ...
- java Vamei快速教程20 GUI
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! GUI(Graphical User Interface)提供了图形化的界面,允许 ...
- java Vamei快速教程14 异常处理
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 程序很难做到完美,不免有各种各样的异常.比如程序本身有bug,比如程序打印时打印机 ...
- POJ-1274 The Perfect Stall---二分图模板
题目链接: https://vjudge.net/problem/POJ-1274 题目大意: 有n个奶牛和m个谷仓,现在每个奶牛有自己喜欢去的谷仓,并且它们只会去自己喜欢的谷仓吃东西,问最多有多少奶 ...