![](https://img-blog.csdnimg.cn/20201014180756927.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
ACM-图论-LCA
暗金色
这个作者很懒,什么都没留下…
展开
-
POJ - 3728 The merchant(dp+LCA)
题目大意:给出N个点,和每个点物品的售价,现在有一个商人,要从u点到v点,他想在路上多赚点钱。他可以从一个城市买物品,然后再卖到另一个城市,但买卖只允许一次,且不能回头走 问最多能赚多少解题思路:果然智商捉急了。。 up数组纪录当前点到lca的最大利润 down数组纪录lca到当前点的最大利润 Max数组lca到当前点的最大值 Min纪录当前点到lca的最小值这样的话,执行tarjan的时原创 2015-08-18 00:20:33 · 1218 阅读 · 0 评论 -
LCA的离线算法 tarjan
对于最近公共祖先问题,我们先来看这样一个性质,当两个节点(u,v)的最近公共祖先是x时,那么我们可以确定的说,当进行后序遍历的时候,必然先访问完x的所有子树,然后才会返回到x所在的节点。这个性质就是我们使用Tarjan算法解决最近公共祖先问题的核心思想。 同时我们会想这个怎么能够保证是最近的公共祖先呢?我们这样看,因为我们是逐渐向上回溯的,所以我们每次访问完某个节点x的一棵子树,我们就将该子树所有节转载 2015-09-12 17:10:00 · 446 阅读 · 0 评论 -
LCA小结
概念 算法ST算法(在线)#include #include const int MAXNODE = 100010;const int MAXEDGE = 200010;struct Edge { int u, v, next; Edge() {} Edge(int u, int v, int next): u(u), v(v), next(next原创 2015-09-13 21:29:45 · 582 阅读 · 0 评论 -
LCA的暴力查询
找两个结点的最近公共祖先,其实要找的就是两条链的第一次相交点 我们假设要找寻u和v的最近公共祖先,把u和v到树根的路径找出来,可以发现,他们的最近公共祖先就是两条链的第一个交点 按照这个思路来想,我们可以先dfs一次,标记每个点的时间戳,然后依据时间戳往前回溯,直到两个结点回溯的时间戳相等。这个时间戳的点就是两个点的最近公共祖先了#include <cstdio>#include <cstri转载 2015-09-13 18:58:22 · 860 阅读 · 1 评论 -
POJ - 1470 Closest Common Ancestors(LCA离线)
题目大意:给出一棵N个结点的树,M个询问,询问的内容是两个结点的最近公共祖先 现在问每个结点作为询问的最近公共祖先结点出现了多少次解题思路:就是LCA离线的裸题了#include <cstdio>#include <cstring>const int MAXNODE = 10010;const int MAXEDGE = 1000010;struct Edge { int u, v,原创 2015-09-13 16:30:08 · 403 阅读 · 0 评论 -
ZOJ - 3195 Design the city(LCA)
题目大意:给出一棵N个结点的无向树,Q个询问,每次询问的是树上的一点到u,v,w这三点的最小距离和解题思路:LCA离线和在线都可以解决 一个点到三个点的最小距离和,就是(2 * dis[u] + 2 * dis[v] + 2 * dis[w] - 2 * dis[lca(u,v)] - 2 * dis[lca(v,w)] - 2 * dis[(u,w)]) /2 除于2是因为边重复计算了两个,这原创 2015-09-12 23:38:13 · 404 阅读 · 0 评论 -
POJ - 1330 Nearest Common Ancestors(LCA在线查询)
题目大意:给你一棵树,要求你输出两个点的LCA解题思路:模版题#include <cstdio>#include <cstring>const int MAXNODE = 100010;const int MAXEDGE = 200010;struct Edge { int u, v, next; Edge() {} Edge(int u, int v, int nex原创 2015-09-12 17:13:47 · 482 阅读 · 0 评论 -
POJ - 1986 Distance Queries(LCA离线)
题目大意:给出N个点,M条边,Q个询问,询问的问题是这两个点之间的距离解题思路:LCA离线的模版,但是要优化,不然会TLE#include <cstdio>#include <cstring>const int MAXNODE = 40010;const int MAXEDGE = 80010;typedef int Type;const Type INF = 0x3f3f3f3f; //1原创 2015-09-12 17:11:55 · 464 阅读 · 0 评论 -
UVALive - 4960 Sensor network(生成树+LCA)
题目大意:给出N个点,M条边,问这N个点形成的生成树的最大权值边-最小权值边的最小值解题思路:先排序,然后按生成树的kruscal算法进行加边,再维护一个最小权值边 加边的时候要考虑一下加下去的边是否会形成环,如果形成环的话,就把环内的最小边去掉,然后再找出这棵新的生成树的最小边等到生成树形成的时候,因为添加进去的新边的权值肯定是最大值的,所以只要只减去之前维护一个的最小值就可以了#include原创 2015-08-22 23:42:26 · 971 阅读 · 0 评论 -
UVA - 11354 Bond(生成树+LCA)
题目大意:给出N个点,M条边,每条边有相应的危险系数 现在有Q个询问,每次询问的是两点之间的路径中的最高危险系数是多少,最高危险系数要最小解题思路:要求的是瓶颈路。按照prim算法求出最小生成树,把1当根结点,遍历这棵最小生成树,纪录每个点的深度,1的深度是1每次询问的时候,就沿路找到两点之间的lca,然后取走的路径的最大值即可#include <cstdio>#include <cstring原创 2015-08-22 23:51:45 · 775 阅读 · 0 评论 -
HDU - 2460 Network(桥+LCA)
题目大意:给出一张图,现在要往这张图上加边,问加完边后,这张图还有多少条桥解题思路:求出连通分量,压缩成点,用桥连接,形成了棵树 每次添加边时,就找一下是否在同一个强连通分量内,如果在同一个强连通分量内,那么桥的数量不变 反之,求出两个点的LCA,并且把LCA到这两个点的桥全部去掉(因为加边后,形成了环,构成了一个新的强连通分量了)#include <cstdio>#include <cstr原创 2015-08-14 01:11:12 · 946 阅读 · 0 评论 -
POJ - 2763 Housewife Wind(LCA+暴力)
题目大意:给出N个点,M条边和一个人的起始位置,然后给出一系列操作 操作A: 0 u 询问这个人走到u这个位置需要几分钟 操作B: 1 i w,将第i条边的权值改成w解题思路:第一个操作比较简单,第二个操作的话也不难。 在dfs纪录结点出现的顺序的时候,顺便记录一下每个点的pre,为第二个操作做准备。 执行第二个操作时,先把本来的边改变一下,再用一次dfs将该边以下的边全部该变一下就好了,原创 2015-08-18 00:07:02 · 935 阅读 · 0 评论 -
HDU - 2586 How far away ?(LCA)
题目大意:给出一张连通图,问两个点之间的距离解题思路:LCA裸题#include <cstdio>#include <cstring>#define N 40010#define M 80010struct Edge{ int to, next, dis;}E[M];struct Question { int x, y;}Q[N];int n, m ,tot;int he原创 2015-08-14 01:22:05 · 739 阅读 · 0 评论 -
POJ - 3417 Network(LCA + DP)
题目大意:给出一棵N个结点的无根树,现在要在上面加上M条边,问,有多少种破坏方式(破坏一条树边,一条新边),能使这张新图变成至少两部分解题思路:首先,假设添加的边为(u,v),那么u – > lca(u,v) –> v – >u就形成了一个环了,也就是说,每条添加的边都会在树上形成一个环本来树上的每条边都是一条桥的,由于加了新的边了,形成了连通分量了,使得边的性质发生了些变化首先,树边在0个连通分量原创 2015-08-18 00:42:14 · 748 阅读 · 0 评论 -
SPOJ-QTREE2 Query on a tree II(暴力+LCA)
题目大意:给出一棵树,3种操作 DIST u,v 询问u到v的距离 KTH k, u, v 询问u到v的路径上的第k大的边的权值解题思路:刚开始以为会爆,结果发现不会 直接暴力存储u到v的路上的所有边,再进行排序,输出第k大的边即可#include <cstdio>#include <cstring>#define N 10010struct Edge{ int to, next原创 2015-08-18 00:48:18 · 797 阅读 · 0 评论 -
HDU - 3078 Network(暴力+LCA)
题目大意:给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上第k大的权值点解题思路:该点的话直接该,找第k大的话直接暴力#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 80010#define M 16001原创 2015-08-18 00:53:53 · 1235 阅读 · 0 评论 -
HDU - 2874 Connections between cities(LCA)
题目大意:给出N个点,M条线,Q个询问,询问的是两点之间的最短距离解题思路:恶心的数据量,一不小心就超空间了 这题给图不是张连通图,是森林,所以计算两点之间的最短距离时还要考虑一下是否在同一棵树中剩下的就是裸LCA了#include <cstdio>#include <cstring>#define N 10010#define M 20010#define C 2000010struct原创 2015-08-14 01:26:04 · 931 阅读 · 0 评论 -
ST算法
求LCA(最近公共祖先)的算法有好多,按在线和离线分为在线算法和离线算法。 离线算法有基于搜索的Tarjan算法较优,而在线算法则是基于dp的ST算法较优。 首先说一下ST算法。 这个算法是基于RMQ(区间最大最小值编号)的 而求LCA就是把树通过深搜得到一个序列,然后转化为求区间的最小编号。 比如说给出这样一棵树。 我们通过深搜可以得到这样一个序列: 节点ver 1 3 1 2 5转载 2015-09-12 16:20:48 · 1595 阅读 · 0 评论