图论--LCA--树上倍增法(在线)】的更多相关文章

Update: 2019.7.15更新 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 万分感谢[宁信]大佬,认认真真地审核了本文章,指出了超过五处错误捂脸,太尴尬了. 重要事情说三遍!!!!! 2019.7.16更新 笔记再次完善,感谢[Ichinose]大佬提出的好问题,并且修改了代码部分的错误注释. 笔记再次完善,感谢[Ichinose]大佬提出的好问题,并且修改了代码部分的…
我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题: 对于两个深度不同的结点, 把深度更深的那个向其父节点迭代, 直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的Lca也就是原两个结点的Lca. 因此第二种情况转化成第一种情况来求解Lca是可行的. 这里我们使用倍增法以最快的速度找到相同的深度,然后开始求LCA.求LCA使用倍增法…
/* * LCA在线算法(倍增法) */ const int MAXN = 10010; const int DEG = 20; struct Edge { int to, next; } edge[MAXN * 2]; int head[MAXN], tot; void addedge(int u, int v) { edge[tot].to = v; edge[tot].next = head[u]; head[u] = tot++; } void init() { tot = 0; mem…
题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力.已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力 输入描述 Input Description 第一行一个n,接下来…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4822 Problem Description Three countries, Red, Yellow, and Blue are in war. The map of battlefield is a tree, which means that there are N nodes and (N – 1) edges that connect all the nodes. Each country…
LCA就是最近公共祖先,比如 节点10和11的LCA就是8,9和3的LCA就是3. 我们这里讲一下用树上倍增来求LCA. 大家都可以写出暴力解法,两个节点依次一步一步往上爬,直到爬到了相同的一个节点. 二树上倍增就是对暴力的优化,改成了一次爬好几步. 具体怎么爬呢?就是两个点每次爬 2^j 步,而 j 满足的是两个点爬到的点不能相同,因为这样可能是公共祖先,但不一定是最近的.在这种条件下要使 j 尽可能的大. 举个例子,比如上图的节点7和8,当 j = 2 时,都爬到了节点 1,然而很显然这不是…
补了一发LCA,表示这东西表面上好像简单,但是细节真挺多. 我学的是树上倍增,倍增思想很有趣~~(爸爸的爸爸叫奶奶.偶不,爷爷)有一个跟st表非常类似的东西,f[i][j]表示j的第2^i的祖先,就是说f[0][x]是父亲,f[1][x]是爷爷,f[2][x]是高祖父(爷爷的爷爷),f[3][x]是远祖父(高祖父的高祖父) 搞个事: 按古制辈份分为:自己,父亲.祖父.曾祖.高祖.天祖.烈祖.太祖.远祖.鼻祖. 扯回来,这个就是倍增的思想,可以方便的实现O(logn)的LCA,现在让你在构图的时候…
首先,什么是LCA? LCA:最近公共祖先 祖先:从当前点到根节点所经过的点,包括他自己,都是这个点的祖先 A和B的公共祖先:同时是A,B两点的祖先的点 A和B的最近公共祖先:深度最大的A和B的公共祖先 树上倍增:预处理nlog2n       求解nlog2n 原理大体描述:两个点都往上找,找到的第一个相同的点,就是他们的LCA 这里会有两个问题: Q1:若两个点深度不同,可能会错开 Q2:若真一个一个往上找,时间太慢 对于Q1,如果两个点深度不同,而我们又需要它们深度相同,那就想办法让他们深…
倍增求LCA: father[i][j]表示节点i往上跳2^j次后的节点 可以转移为 father[i][j]=father[father[i][j-1]][j-1] 整体思路: 先比较两个点的深度,如果深度不同,先让深的点往上跳,浅的先不动,等两个点深度一样时,if 相同 直接返回,if 不同 进行下一步:如果不同,两个点一起跳,j从大到小枚举(其实并不大),如果两个点都跳这么多后,得到的点相等,两个点都不动(因为有可能正好是LCA也有可能在LCA上方),知道得到的点不同,就可以跳上来,然后不…
倍增lca板子洛谷P3379 #include<cstdio> struct E { int to,next; }e[]; ],anc[][],log2n,deep[],n,m,s,ne; ]; void dfs(int x,int fa) { int i,k; vis[x]=; anc[x][]=fa; deep[x]=deep[fa]+; ;i<=log2n;i++) anc[x][i]=anc[anc[x][i-]][i-]; ;k=e[k].next) if(!vis[e[k].…