题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3195

题意: 给出一棵 n 个节点的带边权的树, 有 q 组形如 x, y, z 的询问, 输出 x, y, z之间的最短路径.

思路: 在纸上画下不难发现 x, y, z之间的最短路径就是 x, y, z 两两之间的最短路径和的一半.

我们可以通过 lca 模板求出 x, y, z 两两之间的最短路径, 然后再算下 x, y, z三点之间的最短路径即可.

这题应该是用 RMQ 在线比较好写一点, 用 tarjan 的话记录路径有点麻烦.

代码:

 #include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
using namespace std; const int MAXN = 5e4 + ;
struct node{
int v, w, next;
}edge[MAXN << ]; int dp[MAXN << ][];
int ver[MAXN << ], deep[MAXN << ], first[MAXN];
int dis[MAXN], head[MAXN], vis[MAXN], indx, ip; inline void init(void){
memset(vis, , sizeof(vis));
memset(head, -, sizeof(head));
indx = ;
ip = ;
} void addedge(int u, int v, int w){
edge[ip].v = v;
edge[ip].w = w;
edge[ip].next = head[u];
head[u] = ip++;
} void dfs(int u, int h){
vis[u] = ;
ver[++indx] = u;
deep[indx] = h;
first[u] = indx;
for(int i = head[u]; i != -; i = edge[i].next){
int v = edge[i].v;
if(!vis[v]){
dis[v] = dis[u] + edge[i].w;
dfs(v, h + );
ver[++indx] = u;
deep[indx] = h;
}
}
} void ST(int n){
for(int i = ; i <= n; i++){
dp[i][] = i;
}
for(int j = ; ( << j) <= n; j++){
for(int i = ; i + ( << j) - <= n; i++){
int x = dp[i][j - ], y = dp[i + ( << (j - ))][j - ];
dp[i][j] = deep[x] < deep[y] ? x : y;
}
}
} int RMQ(int l, int r){
int len = log2(r - l + );
int x = dp[l][len], y = dp[r - ( << len) + ][len];
return deep[x] < deep[y] ? x : y;
} int LCA(int x, int y){
int l = first[x], r = first[y];
if(l > r) swap(l, r);
int pos = RMQ(l, r);
return ver[pos];
} int main(void){
bool flag = false;
int n, q, x, y, z;
while(~scanf("%d", &n)){
if(flag) puts("");
flag = true;
init();
for(int i = ; i < n; i++){
scanf("%d%d%d", &x, &y, &z);
addedge(x, y, z);
addedge(y, x, z);
}
dis[] = ;
dfs(, );
ST( * n - );
scanf("%d", &q);
while(q--){
scanf("%d%d%d", &x, &y, &z);
int lca1 = LCA(x, y);
int lca2 = LCA(x, z);
int lca3 = LCA(y, z);
int sol1 = dis[x] + dis[y] - * dis[lca1];
int sol2 = dis[x] + dis[z] - * dis[lca2];
int sol3 = dis[y] + dis[z] - * dis[lca3];
printf("%d\n", (sol1 + sol2 + sol3) >> );
}
}
return ;
}

zoj3195(lca / RMQ在线)的更多相关文章

  1. hdu3078(lca / RMQ在线)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3078 题意: 给出一棵 n 个点的带点权值的树, 接下来有 q 组形如 k, x, y 的输入, 若 ...

  2. hdu 3078(LCA的在线算法)

    Network Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  3. 【Homework】LCA&RMQ

    我校是神校,作业竟然选自POJ,难道不知道“珍爱生命 勿刷POJ”么? 所有注明模板题的我都十分傲娇地没有打,于是只打了6道题(其实模板题以前应该打过一部分但懒得找)(不过感觉我模板还是不够溜要找个时 ...

  4. POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权

    题意: 知道了一颗有  n 个节点的树和树上每条边的权值,对应两种操作: 0 x        输出 当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val   把第 x 条边的权值改为 ...

  5. 算法详解(LCA&RMQ&tarjan)补坑啦!完结撒花(。◕ˇ∀ˇ◕)

    首先,众所周知,求LCA共有3种算法(树剖就不说了,太高级,以后再学..). 1.树上倍增(ST表优化) 2.RMQ&时间戳(ST表优化) 3.tarjan(离线算法)不讲..(后面补坑啦!) ...

  6. LCA最近公共祖先 ST+RMQ在线算法

    对于一类题目,是一棵树或者森林,有多次查询,求2点间的距离,可以用LCA来解决.     这一类的问题有2中解决方法.第一种就是tarjan的离线算法,还有一中是基于ST算法的在线算法.复杂度都是O( ...

  7. HDU 2586 How far away ?(经典)(RMQ + 在线ST+ Tarjan离线) 【LCA】

    <题目链接> 题目大意:给你一棵带有边权的树,然后进行q次查询,每次查询输出指定两个节点之间的距离. 解题分析:本题有多重解决方法,首先,可用最短路轻易求解.若只用LCA解决本题,也有三种 ...

  8. Tourists Gym - 101002I LCA——dfs+RMQ在线算法

    LCA(Least Common Ancestors),即最近公共祖先,是指这样一个问题:在有根树中,找出某两个结点u和v最近的公共祖先(另一种说法,离树根最远的公共祖先). 知识需求:1)RMQ的S ...

  9. hdu2874(lca / tarjan离线 + RMQ在线)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2874 题意: 给出 n 个顶点 m 条边的一个森林, 有 k 个形如 x y 的询问, 输出 x, ...

随机推荐

  1. spring boot: 在maven中装入springframework框架

    1.在maven 的pom.xml中加入 <dependency> <groupId>org.springframework</groupId> <artif ...

  2. node.js+express验证码的实现

    安装ccap库 npm install ccap var ccap = require(); var captcha = ccap({ width:190, height:50, offset:30, ...

  3. ZOJ 2724 Windows Message Queue (二叉堆,优先队列)

    思路:用优先队列 priority_queue,简单 两种方式改变队列 的优先级 (默认的是从大到小) #include<iostream> #include<queue> # ...

  4. HDU3037Saving Beans(组合数+lucas定理)

    Problem Description Although winter is far away, squirrels have to work day and night to save beans. ...

  5. bzoj 3302&2447&2103 树的双中心 树形DP

    题目: 题解: bzoj 3302 == 2447 == 2103 三倍经验 首先我们考虑枚举两个中心的位置,然后统计答案. 我们发现,一定有一部分点离第一个中心更近,另一部分点离第二个中心更近 如果 ...

  6. iOS项目添加PCH文件

    1.单击Info.plist右键单击->New File->Other->PCH File创建PCH文件 文件名设置成:项目名-Prefix  ->点击Create,创建成功. ...

  7. zoj 3872

    D - Beauty of Array Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu S ...

  8. springMVC绑定json参数之二(2.1.1)

    二.springmvc 接收不同格式的json字符串 1.首先扫盲几个知识点: 例子如下: 前台传递json对象(这里uu[0]的名字uu要和Test对象中的属性List<User>名称对 ...

  9. Jenkins配置邮件SMTP(使用QQ邮箱)

    一.QQ邮箱中开启SMTP服务 进入QQ邮箱的设置页面,选择开启POP3/SMTP服务 需要发送一条短信开启服务,成功后,会收到一个密码,一定要截图.复制密码保存好 二.Jenkins中配置SMTP ...

  10. javascript面向对象的测试实例