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).通过递归思想和并查集来寻找最近公共祖先 ...
随机推荐
- while if 循环判断
temp=input("猜一下我想的那个数字吧:") guess=int(temp) while guess!=8: temp=input("诶呀错误了在输入一次吧:&q ...
- SQL联合索引 与 单一列的索引
SQL联合索引 与 单一列的索引 标签: sqlwebobjectstatistics优化磁盘 2012-06-12 13:46 27992人阅读 评论(1) 收藏 举报 分类: 数据库(94) ...
- 转:使用Mongo Connector和Elasticsearch实现模糊匹配
原文来自于:http://www.csdn.net/article/2014-09-01/2821485-how-to-perform-fuzzy-matching-with-mongo-connec ...
- 关于C#的委托
作者 陈嘉栋(慕容小匹夫) 阅读目录 0x00 前言 0x01 从观察者模式说起 0x02 向Unity3D中的SendMessage和BroadcastMessage说拜拜 0x03 认识回调函数 ...
- hdu 5139 Formula
http://acm.hdu.edu.cn/showproblem.php?pid=5139 思路:这道题要先找规律,f(n)=n!*(n-1)!*(n-2)!.....1!; 不能直接打表,而是离 ...
- ESXI转HYPER-V,问题接二连三啊(VMDK转VHD)
首先说软件: 要不是用SCVMM来转的话,我用得最爽的还是WINIMAGE,自然流畅.其它的都有各种问题. 其次说说配置更改: 如果原ESXI里只有一个硬盘,一切好说,如果里面挂载了两个,甚至三个硬盘 ...
- 2句代码轻松实现WPF最大化不遮挡任务栏并且具有边框调节效果
原文:2句代码轻松实现WPF最大化不遮挡任务栏并且具有边框调节效果 相信刚入门的菜鸟跟我一样找遍了百度谷歌解决最大化遮挡任务栏的方法大多方法都是HOOK一大堆API声明 最近在敲代码的时候无意中发现有 ...
- Qt入门(11)——Qt插件
Qt提供了一个简单地插件接口,可以轻松地生成作为独立组件的定制数据库驱动.图象格式.文本编解码器(text codec).风格(style)和部件.警告:Qt 3.0.5对插件的一些方面做了改变,具体 ...
- [JAVA关键字] synchronized
synchronized, Example: public synchronized void XXX() {} 参考 http://wenku.baidu.com/link?url=ecb1Zivf ...
- tcpCopy
tcpcopy是一种应用请求复制(基于tcp的packets)工具,其应用领域较广,我们曾经应用于网易的广告投放系统,urs系统,nginx hmux协议开发等系统,避免了上线带来的很多问题. 总体说 ...