题意:给定一棵树,求任意两点之间的距离。

思路:由于树的特殊性,所以任意两点之间的路径是唯一的。u到v的距离等于dis(u) + dis(v) - 2 * dis(lca(u, v)); 其中dis(u)表示u到根节点的距离。

RMQ求LCA,过程如下,摘自http://dongxicheng.org/structure/lca-rmq/

在线算法DFS+ST描述(思想是:将树看成一个无向图,u和v的公共祖先一定在u与v之间的最短路径上):

(1)DFS:从树T的根开始,进行深度优先遍历(将树T看成一个无向图),并记录下每次到达的顶点。第一个的结点是root(T),每经过一条边都记录它的端点。由于每条边恰好经过2次,因此一共记录了2n-1个结点,用E[1, ... , 2n-1]来表示。

(2)计算R:用R[i]表示E数组中第一个值为i的元素下标,即如果R[u] < R[v]时,DFS访问的顺序是E[R[u], R[u]+1, …, R[v]]。虽然其中包含u的后代,但深度最小的还是u与v的公共祖先。

(3)RMQ:当R[u] ≥ R[v]时,LCA[T, u, v] = RMQ(L, R[v], R[u]);否则LCA[T, u, v] = RMQ(L, R[u], R[v]),计算RMQ。

由于RMQ中使用的ST算法是在线算法,所以这个算法也是在线算法。

代码如下(LCA模板):

//LCA algorithm templet
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm> using namespace std;
typedef long long ll;
const int maxn = ;
int tot, head[maxn];
struct Edge {
int to, next;
int w;
}edge[maxn<<];//edge
int Euler[maxn<<];//Euler sequence
int R[maxn];//the R one visit
int dep[maxn<<];//depth
int dis[maxn<<];//dis[i] represent the distance between i and root int cnt;//the counter
void init()
{
tot = ;
cnt = ;
memset(head, -, sizeof(head));
memset(R, , sizeof(R));
memset(dis, , sizeof(dis));
}
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u, int fa, int depth, int dist)
{
Euler[++cnt] = u;
dis[cnt] = dist;
dep[cnt] = depth;
R[u] = cnt;
for (int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa) continue;
dfs(v, u, depth + , dist + edge[i].w);
Euler[++cnt] = u;
dis[cnt] = dist;
dep[cnt] = depth;
}
}
int Rmin[maxn * ][];//Rmin represent the number(order number) of node
void RMQ(int n)
{
for (int i = ; i <= n; i++)
Rmin[i][] = i;//initalization
int k = (int)log2(n);
for (int j = ; j <= k; j++)
{
for (int i = ; i + ( << j) - <= n; i++)//按照dep来找最小值
Rmin[i][j] = dep[Rmin[i][j - ]] < dep[Rmin[i + ( << (j - ))][j - ]] ? Rmin[i][j - ] : Rmin[i + ( << (j - ))][j - ];
}
}
//找到u和v的距离
int query(int u, int v)
{
int l = R[u], r = R[v];
if (l > r) swap(l, r);
int k = (int)log2(r - l + );
int tmp = dep[Rmin[l][k]] < dep[Rmin[r - ( << k) + ][k]] ? Rmin[l][k] : Rmin[r - ( << k) + ][k];
//return Euler[tmp];//这里是返回u和v的公共祖先
return dis[l] + dis[r] - * dis[tmp];//这里返回距离
}
int main()
{
int n, tmp;
while (~scanf("%d %d", &n, &tmp))
{
init();
int u, v, w;
for (int i = ; i < n; i++)
{
scanf("%d %d %d %*s", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
}
dfs(, , , );
RMQ(cnt);
int Q;
scanf("%d", &Q);
while (Q--)
{
scanf("%d %d", &u, &v);
printf("%d\n", query(u, v));
}
}
return ;
}

POJ 1986(LCA and RMQ)的更多相关文章

  1. POJ 1986 Distance Queries(Tarjan离线法求LCA)

    Distance Queries Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 12846   Accepted: 4552 ...

  2. POJ.1986 Distance Queries ( LCA 倍增 )

    POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...

  3. POJ 1986 Distance Queries LCA两点距离树

    标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...

  4. POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)

    POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...

  5. LCA和RMQ

    下面写提供几个学习LCA和RMQ的博客,都很通熟易懂 http://dongxicheng.org/structure/lca-rmq/ 这个应该是讲得最好的,且博主还有很多其他文章,可以读读,感觉认 ...

  6. ZOJ 3195 Design the city LCA转RMQ

    题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...

  7. [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]

    参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...

  8. lca转RMQ

    这个博客写得好 #include <stdio.h> #include <vector> #include <string.h> using namespace s ...

  9. poj 1330 LCA最近公共祖先

    今天学LCA,先照一个模板学习代码,给一个离线算法,主要方法是并查集加上递归思想. 再搞,第一个离线算法是比较常用了,基本离线都用这种方法了,复杂度O(n+q).通过递归思想和并查集来寻找最近公共祖先 ...

随机推荐

  1. nginx——rewrite模块

    1.什么是Nginx的Rewrite规则? Rewrite主要的功能就是实现URL的重写,Nginx的Rewrite规则采用PCRE(Perl Compatible Regular Expressio ...

  2. [r]Setting up Django and your web server with uWSGI and nginx

    Setting up Django and your web server with uWSGI and nginx This tutorial is aimed at the Django user ...

  3. C#面试-关于const和readonly(看了一个点赞很多的帖子有感而发!)

    前景提要: 最近大家都在面试,讨论最多.最基础的问题,莫过于“关于const和readonly常见的笔试题剖析”,等等的大牛解析.我就是一个小菜,只不过,有点不敢苟同大牛的意见.废话少说,进入重点. ...

  4. Java Web开发介绍

    转自:http://www.cnblogs.com/pythontesting/p/4963021.html Java Web开发介绍 简介 Java很好地支持web开发,在桌面上Eclipse RC ...

  5. Unity3d项目合作 场景的合并和还原

    Unity3d项目合作  场景的合并和还原 特别声明:转载自Unity3D研究院 如何侵犯版权,请通知我删除! 摘要: 导出Unity场景的所有游戏对象信息,一种是XML一种是JSON.本篇文章我们把 ...

  6. 如何在不影响数据库的正常使用的情况下得到数据的完整.mdf和.ldf文

    一:完整备份数据库 二:还原数据库 四:分离数据库即可得到.mdf和.ldf文件

  7. IOS的 testflight测试设置

    管理员邀请参与者 1.登录开发者账号https://developer.apple.com/account 2.进入后,点击ituns connect 3.点击进入用户和职能 4.在用户栏点击添加按钮 ...

  8. HDOJ 2802 F(N)

    Problem Description Giving the N, can you tell me the answer of F(N)? Input Each test case contains ...

  9. pygame学习资料

    pygame下载地址: https://bitbucket.org/pygame/pygame/downloads 12岁的少年教你用Python做小游戏 Beginning Game Program ...

  10. poj1026

    题目大意:暗号 Bod 和 Alice 计划使用一种全新的编码方案,令人惊讶的是这不是一个公开的公匙密码,但是他们的编码基于密匙,在Philadelphia on February 16th他们的会议 ...