倍增法求lca:暗的连锁】的更多相关文章

How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 14685    Accepted Submission(s): 5554 Problem Description There are n houses in the village and some bidirectional roads connecting…
倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可以在O(logn)的时间内求出求出任意节点的任意祖先. 然后先把两个节点中转化为深度相同的节点,然后一起向上递增,知道找到相同的节点,该节点就是这两个节点的最近公共祖先. 代码实现: #include<cstdio> #include<iostream> #define N 42000…
倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可以先把两个的深度提到同一水平,在一步一步往上跳,直到两个结点有了一个公共祖先,依照算法流程,这就是least common ancestor. 但是如果这样一步步地往上未免太让人着急,为了提高一下效率,便不再每次只跳一步,而跳\(2^i\)步.一般的,先这样蹦蹦跳跳跳上去直到两个结点相平,在两个一起…
我们找的是任意两个结点的最近公共祖先, 那么我们可以考虑这么两种种情况: 1.两结点的深度相同. 2.两结点深度不同. 第一步都要转化为情况1,这种可处理的情况. 先不考虑其他, 我们思考这么一个问题: 对于两个深度不同的结点, 把深度更深的那个向其父节点迭代, 直到这个迭代结点和另一个结点深度相同, 那么这两个深度相同的结点的Lca也就是原两个结点的Lca. 因此第二种情况转化成第一种情况来求解Lca是可行的. 这里我们使用倍增法以最快的速度找到相同的深度,然后开始求LCA.求LCA使用倍增法…
对于有根树T的两个结点u.v,最近公共祖先x=LCA(u,v)表示一个结点x,满足x是u.v的祖先且x的深度尽可能大. 如图,根据定义可以看出14和15的最近公共祖先是10,   15和16的最近公共祖先是1,     6和5的最近公共祖先是5...... 假如我要求14和16的最近公共祖先,要怎么做呢? 最暴力的做法,就是先看14和16在不在同一层,如果他们不在同一层,那么较深的那个点往上爬(即距离根较远的那个点) 一直爬,爬到两点的深度一样 当两点深度一样时,判断他们是否在同一个点上,如果不…
https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to,next; }e[]; ],num=,N,n,m,ans; ][],depth[]; ],w[]; inline void add(int x,int y) { e[++num].to=y,e[num].next=head[x],head[x]=num; } inline void read(int &…
1.cojs 186. [USACO Oct08] 牧场旅行 ★★   输入文件:pwalk.in   输出文件:pwalk.out   简单对比时间限制:1 s   内存限制:128 MB n个被自然地编号为1..n奶牛(1<=n<=1000)正在同样被方便的编号为1..n的n个牧场中吃草.更加自然而方便的是,第i个奶牛就在第i个牧场中吃草. 其中的一些对牧场被总共的n-1条双向通道的一条连接.奶牛可以通过通道.第i条通道连接的两个牧场是A_i和B_i(1<=A_i<=N;1&l…
#include <iostream> #include <vector> #include <algorithm> #define MAXN 100 //2^MAXLOG2>=最大深度 #define MAXLOG2 7 using namespace std; vector<int>G[MAXN]; int depth[MAXN]; int ancestor[MAXN][MAXLOG2]; void creat()//输入并存储树 { int n,…
Luogu P3379 最近公共祖先 原题展现 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入格式 第一行包含三个正整数 \(N,M,S\),分别表示树的结点个数.询问的个数和树根结点的序号. 接下来 \(N-1\) 行每行包含两个正整数 \(x, y\),表示 \(x\) 结点和 \(y\) 结点之间有一条直接连接的边(数据保证可以构成树). 接下来 \(M\) 行每行包含两个正整数 \(a, b\),表示询问 \(a\) 结点和 \(b\) 结点的最近公共祖先…
解决什么问题:区间查询最值 倍增思想:每次得出结果的范围呈2的幂次增长,有人说相当于二分,目前我觉得相当于线段树的查找. 具体理解看代码: /*倍增法求ST*/ #include<math.h> #include<iostream> #include<stdio.h> #include<string.h> using namespace std; int main() { int n,dp[110][110]; memset(dp,0,sizeof(dp))…