在一棵树上 求2个点的最短距离。那么首先利用LCA找到2个点的近期公共祖先

公式:ans = dis(x) + dis(y) - 2 * dis(lca(x,y))

这里的dis(x)指的上x距离根节点的距离

注意一些细节方面,比方数组的越界问题:

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int maxn = 45555;
struct Edge{
int to;
LL dist;
Edge(int to,LL dist):to(to),dist(dist){};
};
int n,m;
int deep[maxn],pa[maxn][22];
LL dis[maxn];
vector<Edge>G[maxn];
void init(){
memset(pa,-1,sizeof(pa));
for(int i = 1; i <= n; i++) G[i].clear();
}
//----------------LAC---------------------------
void dfs(int pos,int d,LL dist){
//printf("[%d %d]\n",pos,dist);
deep[pos] = d;
dis[pos] = dist;
int Size = G[pos].size();
for(int i = 0; i < Size; i++)
dfs(G[pos][i].to,d + 1,dist + G[pos][i].dist);
}
void lca_init(){
for(int j = 1; (1 << j) <= n; j++)
for(int i = 1; i <= n; i++)
if(pa[i][j - 1] != -1)
pa[i][j] = pa[pa[i][j - 1]][j - 1];
}
int lca(int a,int b){
if(a == b)
return a;
if(deep[a] < deep[b]) swap(a,b);
int i;
for(i = 0;(1 << i) <= deep[a]; i++);
for(int j = i; j >= 0; j--)
if(pa[a][j] != -1 && deep[pa[a][j]] >= deep[b])
a = pa[a][j];
if(a == b)
return b;
for(int j = i; j >= 0; j--)
if(pa[a][j] != -1 && deep[pa[a][j]] != deep[pa[b][j]]){
a = pa[a][j];
b = pa[b][j];
}
return pa[a][0];
}
//-------------------------------------------------
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
int x,y,z;
init();
for(int i = 0; i < n - 1; i++){
scanf("%d%d%d",&x,&y,&z);
G[x].push_back(Edge(y,z));
pa[y][0] = x;
}
for(int i = 1; i <= n; i++)if(pa[i][0] == -1){
dfs(i,0,0);
break;
}
lca_init();
for(int i = 0; i < m; i++){
scanf("%d%d",&x,&y);
LL ans = dis[x] + dis[y] - 2 * dis[lca(x,y)];
printf("%I64d\n",ans);
}
}
return 0;
}

【HDU 2586】LCA模板的更多相关文章

  1. HDU 2586 (LCA模板题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2586 题目大意:在一个无向树上,求一条链权和. 解题思路: 0 | 1 /   \ 2      3 ...

  2. [hdu 2586]lca模板题(在线+离线两种版本)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 在线版本: 在线方法的思路很简单,就是倍增.一遍dfs得到每个节点的父亲,以及每个点的深度.然后 ...

  3. HDU 2586 ( LCA/tarjan算法模板)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,d ...

  4. hdu 2586(LCA在线ST)

    How far away ? Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission(s): A ...

  5. HDU 2586 LCA

    题目大意: 多点形成一棵树,树上边有权值,给出一堆询问,求出每个询问中两个点的距离 这里求两个点的距离可以直接理解为求出两个点到根节点的权值之和,再减去2倍的最近公共祖先到根节点的距离 这是自己第一道 ...

  6. hdu - 2586 (LCA板子题)

    传送门 (这次的英文题面要比上一个容易看多了) (英语蒟蒻的卑微) 又是一个很裸的LCA题 (显然,这次不太容易打暴力咧) (但听说还是有大佬用dfs直接a掉了) 正好 趁这个机会复习一下LCA 这里 ...

  7. hdu 2586 lca在线算法(朴素算法)

    #include<stdio.h> #include<string.h>//用c/c++会爆栈,用g++ac #define inf 0x3fffffff #define N ...

  8. HDU 2586 + HDU 4912 最近公共祖先

    先给个LCA模板 HDU 1330(LCA模板) #include <cstdio> #include <cstring> #define N 40005 struct Edg ...

  9. HDU - 2586 How far away ?(LCA模板题)

    HDU - 2586 How far away ? Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & ...

  10. HDU 2586——How far away ?——————【LCA模板题】

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

随机推荐

  1. 【jQuery】select动态追加的option选中

    var turnUpHidden = $("input[name='turnUpHidden']").val(); if(turnUpHidden != "") ...

  2. jenkins报:反向代理设置有误

    1.如图所示: 2.点击更多信息,查看解决办法: https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+says+my+reverse+proxy+s ...

  3. c#抓去网页

    c#利用WebClient和WebRequest获取网页源代码的比较 2011-11-28 10:26:42     我来说两句 收藏 我要投稿 C#中一般是可以利用WebClient类和WebReq ...

  4. XHTML学习要点

    目标 掌握XHTML语法,能正确书写出符合规则的文档. 要点 基本概念,与HTML有什么不一样 基本语法规则: XHTML 文档必须拥有一个根元素 标签名.属性名称必须小写 属性值必须加引号 属性不能 ...

  5. OpenCV学习(2) OpenCV的配置

          下面我们在VS2010中编写一个简单的OpenCV程序,来看看如何在程序中使用OpenCV. 创建一个新的Win32 控制台程序,附加选项为空工程(empty project),并添加一个 ...

  6. Android -- Messenger与Service

    如果你需要你的service和其他进程通信,那么你可以使用一个Messenger来提供这个接口. 这种方法允许你在不使用 AIDL的情况下,进行跨进程通信IPC. 实现步骤 下面是一个如何使用 Mes ...

  7. 在帝国cms中新建只具有编辑某些栏目权限的后台用户或新建编辑用户在选择栏目时不能选择问题解决方法

    在帝国cms中,鉴于有些部门只允许编辑自己部门所负责栏目内的新闻.信息等,所以创建只具有某一栏目或某几个栏目的编辑权限的后台用户至关重要. 1. 点击上面导航栏中的“用户”按钮 2. 点击左侧菜单中的 ...

  8. Sqlserver 中添加数据库登陆账号并授予数据库所有者权限

    Sqlserver 中添加数据库登陆账号并授予数据库所有者权限 USE master GO --通过sp_addlogin创建登录名 --DEMO:登陆账号 --123456:登陆密码 ' --切换数 ...

  9. SSIS实践入门2:批量包的调度和SQLServer代理作业配置

    趁着上一篇文章的余温,我们继续研究一下SSIS中多个包如何调度,难道需要一个包一个包的配置调度程序吗?显然不是的,接下来我们就说一说在SSIS应用中如何批量的调度所有的作业,本文只讲述一个基本的逻辑过 ...

  10. Oracle Spatial 创建空间表、添加空间原表信息、添加删除空间索引

    一.创建空间表 创建一个空间表tbsvrc_buffer_t ,SQL如下: create table tbsvrc_buffer_t(  ID      VARCHAR2(50) not null, ...