POJ 1986(LCA and RMQ)
题意:给定一棵树,求任意两点之间的距离。
思路:由于树的特殊性,所以任意两点之间的路径是唯一的。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)的更多相关文章
- POJ 1986 Distance Queries(Tarjan离线法求LCA)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12846 Accepted: 4552 ...
- POJ.1986 Distance Queries ( LCA 倍增 )
POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...
- POJ 1986 Distance Queries LCA两点距离树
标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...
- POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)
POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...
- LCA和RMQ
下面写提供几个学习LCA和RMQ的博客,都很通熟易懂 http://dongxicheng.org/structure/lca-rmq/ 这个应该是讲得最好的,且博主还有很多其他文章,可以读读,感觉认 ...
- ZOJ 3195 Design the city LCA转RMQ
题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...
- [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 ...
- lca转RMQ
这个博客写得好 #include <stdio.h> #include <vector> #include <string.h> using namespace s ...
- poj 1330 LCA最近公共祖先
今天学LCA,先照一个模板学习代码,给一个离线算法,主要方法是并查集加上递归思想. 再搞,第一个离线算法是比较常用了,基本离线都用这种方法了,复杂度O(n+q).通过递归思想和并查集来寻找最近公共祖先 ...
随机推荐
- Java认证:JavaRunnable线程编写接口代码
Java认证:JavaRunnable线程编写接口代码.JavaRunnable线程如何才能更好的适应目前的编程环境呢?下面我们就看看如何才能更好的进行相关环境.希望下面的文章对大家有所帮助.Java ...
- react-redux原理
react-redux原理分析 写在前面 之前写了一篇分析Redux中Store实现的文章(详见:Redux原理(一):Store实现分析),突然意识到,其实React与Redux并没有什么直接的联系 ...
- JavaScript的组成—ECMAScript、BOM和DOM
JavaScript 是一种基于 ECMAScript 规范的脚本语言,并在此基础上进行了自己的封装.ECMAScript 不是一种编程语言,仅仅是一种脚本语言规范,由欧洲计算机协会制定和发布,任 ...
- duplicate symbols for architecture arm64 (Xcode error)
比如 duplicate symbol _NewBase64Encode_soomla in: /Users/UnityGame/Libraries/Plugins/iOS/Soomla/libSoo ...
- 转:100个高质量Java开发者博客
原文来自于:http://www.importnew.com/7469.html ImportNew注:原文中还没有100个.作者希望大家一起来推荐高质量的Java开发博客,然后不段补充到这个列表.欢 ...
- BZOJ 2572 高速公路
Description Y901高速公路是一条重要的交通纽带,政府部门建设初期的投入以及使用期间的养护费用都不低,因此政府在这条高速公路上设立了许多收费站.Y901高速公路是一条由N-1段路以及N个收 ...
- 自动垂直居中的js
var _htmlheight; function start(){ _htmlheight=document.body.scrollHeight; resize(); /*$("#copy ...
- Bug in Code
Coder-Strike 2014 - Finals (online edition, Div. 1) C:http://codeforces.com/problemset/problem/420/C ...
- 我的VSTO之路(五):Outlook初步开发之联系人扩展
原文:我的VSTO之路(五):Outlook初步开发之联系人扩展 上一讲我们完成对Word的介绍,文本开始,我将着重介绍Outlook.Outlook是微软Office中一个非常实用的工具,尤其在一个 ...
- Buffer Sort
BUFFER (SORT) Description Performs a memory sort on a row source CREATE TABLE t1 (c01 NUMBER); CREAT ...