求LCA(近期公共祖先)的算法有好多,按在线和离线分为在线算法和离线算法. 离线算法有基于搜索的Tarjan算法较优,而在线算法则是基于dp的ST算法较优. 首先说一下ST算法. 这个算法是基于RMQ(区间最大最小值编号)的,不懂的能够这里学习一些 而求LCA就是把树通过深搜得到一个序列,然后转化为求区间的最小编号. 比方说给出这样一棵树. watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveTk5MDA0MTc2OQ==/font/5a6L5L2T/fo…
LCA(最近公共祖先)的求法有多种,这里先介绍第一种:在线算法. 声明一下:下面的内容参考了http://www.cnblogs.com/scau20110726/archive/2013/05/26/3100812.html. 在线算法就是利用了DFS和RMQ两种算法,它先是预处理好所有情况,然后根据输入输出答案,在输入比较多的时候用比较好. 上面两张图介绍了在线算法的做法,要理解并不难,下面附上实现代码: /******************************* dfs实现代码 **…
http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树,求出树上任意两点之间的距离. 思路: 这道题可以利用LCA来做,记录好每个点距离根结点的距离,然后只要计算出两点的LCA,这样一来答案就是distance[u]+distance[v]-2distance[LCA]. #include<iostream> #include<algorithm> #include<cstring> #include<cst…
#include<stdio.h> #include<string.h>//用c/c++会爆栈,用g++ac #define inf 0x3fffffff #define N 41000 struct node { int u,v,w,next; }bian[N*2]; int head[N],yong; int pre[N],dis[N],deep[N]; void addedge(int u,int v,int w) { bian[yong].u=u; bian[yong].v…
2018.9.10 0:40 重新敲一遍,然后很认真的写了注释,方便自己和队友看,刚过去的一天的下午打网络赛有一题用到了这个,但是没写注释,队友改板子有点伤,因为我没注释... 以后写博客,代码要写注释,要把题目意思写上... 我好捞啊... How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 21408    …
链接: How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11204    Accepted Submission(s): 4079 Problem Description There are n houses in the village and some bidirectional roads connec…
链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 [题意] 给出一个N 个和N-1条边的连通图,询问任意两点间的距离.N<=40000 . [分析] 点太多了,用最短路算法来求超时.只够求一个点的单源最短路,而且不能用O(n2)的算法.正确的做法就是求出两点的最近公共祖先,利用点v到树的根节点距离dis[v]来换算.设要求的两点分别为u和v, 那么u和v的距离d=dis[u]+dis[v]-2*dis[LCA(u,v)] . 现在还有一个问题就是…
hdu2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4183    Accepted Submission(s): 1598 Problem Description There are n houses in the village and some bidirectional roads co…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路:在求解最近公共祖先的问题上,用到的是Tarjan的思想,从根结点开始形成一棵深搜树,非常好的处理技巧就是在回溯到结点u的时候,u的子树已经遍历, 这时候才把u结点放入合并集合中,这样u结点和所有u的子树中的结点的最近公共祖先就是u了,u和还未遍历的所有u的兄弟结点及子树中的最近公共祖先就是 u的父亲结点.以此类推.这样我们在对树深度遍历的时候就很自然的将树中的结点分成若干的集合,两个集合…
How far away &题解: 和上篇是一样的题,这用的是lca方法做的, 不知道为什么,把数组开到80000 就a了 >_< 哈 我现在知道为什么了,因为我的rmq数组没有乘2,rmq比较的是depth数组,但是depth数组的范围是maxn*2,所以rmq的数组乘2就好了 &代码: #include <cstdio> #include <bitset> #include <iostream> #include <set>…