当前位置:网站首页>Multiply LCA (nearest common ancestor)
Multiply LCA (nearest common ancestor)
2022-07-02 12:10:00 【Tooth decay music】
Multiply :
hold n Fold the simulation into
simulation ( It's understandable ), The reason to use 2 Is due to 2 To the power of, you can round up all positive integers
Ring problem (https://oi-wiki.org/basic/binary-lifting/): Here, only the multiplication method is explained
Its idea is to find x + k The value of this circle , then m Secondary disassembly
Get the answer for the first time . Have a conclusion : most n This cycle can return to the origin , Therefore, each cycle must be neither heavy nor leaky .
List of questions : https://www.luogu.com.cn/training/203#problems
LCA:
The common ancestor of two nodes in the tree ( Looking up, you can find the ancestor node that the nearest two points can reach at the same time )
Some properties : https://oi-wiki.org/graph/lca/
violence :
dfs Look for... Layer by layer
The board of senior students , It's probably such a reason
void dfs(int u, int fa)
father[u] = fa;
deep[u] = deep[fa] + 1;
for (int i = head[u]; ~i; i = edge[i].pre){
int v = edge[i].to;
if(v != fa)
dfs(v, u);
}
}
int lca1(int u, int v){
while(u != v){
if(deep[u] < deep[v]){
swap(u, v);
}
u = father[u];
}
return u;
}
int lca2(int u, int v){
if(deep[u] < deep[v]){
swap(u, v);
}
while(deep[u] > deep[v]){
u = father[u];
}
while(u != v){
u = father[u];
v = father[v];
}
return u;
}Multiply LCA:
Preprocessing x Of
The ancestors ( Each jump
)+ Split the height difference between two nodes
P3379 【 Templates 】 Recent public ancestor (LCA)(https://www.luogu.com.cn/problem/P3379)
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 5e5 + 5;
const int DEG = 30;
#define re(a) memset(a, -1, sizeof(a))
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;
re(head);
}
int fa[maxn][DEG], deg[maxn];
void bfs(int root){
queue<int> que;
deg[root] = 0;
fa[root][0] = root;
que.push(root);
while(!que.empty()){
int tmp = que.front();
que.pop();
for(int i = 1; i < DEG; ++i){
fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
}
for (int i = head[tmp]; i != -1; i = edge[i].next){
int v = edge[i].to;
if(v == fa[tmp][0])
continue;
deg[v] = deg[tmp] + 1;
fa[v][0] = tmp;
que.push(v);
}
}
}
int lca(int u, int v){
if(deg[u] > deg[v]){
swap(u, v);
}
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for (int det = hv - hu, i = 0; det; det >>= 1, ++i){
if(det & 1)
tv = fa[tv][i];
}
if(tu == tv)
return tu;
for(int i = DEG - 1; i >= 0; --i){
if(fa[tu][i] == fa[tv][i]){
continue;
}
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][0];
}
bool flag[maxn];
int main(){
int n, m, s;
init();
memset(flag, false, sizeof(flag));
cin >> n >> m >> s;
for (int i = 1; i < n; ++i){
int a, b;
cin >> a >> b;
addedge(a, b);
addedge(b, a);
flag[b] = true;
}
int root;
for (int i = 1; i <= n; ++i){
if(!flag[i]) {
root = i;
break;
}
}
bfs(s);// The root node
for (int i = 0; i < m; ++i){
int a, b;
cin >> a >> b;
cout << lca(a, b) << endl;
}
return 0;
}topic :
Nearest Common Ancestors(https://vjudge.net/problem/POJ-1330)
Copy down the upper board and change it
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 5e5 + 5;
const int DEG = 30;
#define re(a) memset(a, -1, sizeof(a))
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;
re(head);
}
int fa[maxn][DEG], deg[maxn];
void bfs(int root){
queue<int> que;
deg[root] = 0;
fa[root][0] = root;
que.push(root);
while(!que.empty()){
int tmp = que.front();
que.pop();
for(int i = 1; i < DEG; ++i){
fa[tmp][i] = fa[fa[tmp][i - 1]][i - 1];
}
for (int i = head[tmp]; i != -1; i = edge[i].next){
int v = edge[i].to;
if(v == fa[tmp][0])
continue;
deg[v] = deg[tmp] + 1;
fa[v][0] = tmp;
que.push(v);
}
}
}
int lca(int u, int v){
if(deg[u] > deg[v]){
swap(u, v);
}
int hu = deg[u], hv = deg[v];
int tu = u, tv = v;
for (int det = hv - hu, i = 0; det; det >>= 1, ++i){
if(det & 1)
tv = fa[tv][i];
}
if(tu == tv)
return tu;
for(int i = DEG - 1; i >= 0; --i){
if(fa[tu][i] == fa[tv][i]){
continue;
}
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][0];
}
bool flag[maxn];
int main(){
int t;
cin >> t;
while(t--){
int n;
init();
memset(flag, false, sizeof(flag));
cin >> n;
for (int i = 1; i < n; ++i){
int a, b;
cin >> a >> b;
addedge(a, b);
addedge(b, a);
flag[b] = true;
}
int root;
for (int i = 1; i <= n; ++i){
if(!flag[i]) {
root = i;
break;
}
}
bfs(root);// The root node
int a, b;
cin >> a >> b;
cout << lca(a, b) << endl;
}
return 0;
}Wrong hemp , I'll make it up when I have a chance
Post a passable code
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 1e5 + 5;
#define re(a) memset(a, 0, sizeof(a))
//other code
vector<int> adj[maxn], cost[maxn];
int dis[maxn], up[maxn][21], dep[maxn];
void clear(int n){
for (int i = 1; i <= n; ++i){
dis[i] = 0;
adj[i].clear();
cost[i].clear();
dep[i] = 0;
for (int j = 0; j <= 18; ++j)
up[i][j] = 0;
}
}
void dfs(int s, int p){
if(p != -1)
up[s][0] = p;
for (int i = 1; i <= 18; ++i)
up[s][i] = up[up[s][i - 1]][i - 1];
for (int i = 0; i < adj[s].size(); ++i){
int v = adj[s][i];
int d = cost[s][i];
if(v == p)
continue;
dis[v] = dis[s] + d;
dep[v] = dep[s] + 1;
dfs(v, s);
}
}
int lca(int a, int b){
if(dep[a] > dep[b])
swap(a, b);
int d = dep[b] - dep[a];
for (int i = 18; i >= 0; --i){
if(d & (1 << i))
b = up[b][i];
}
if (a == b)
return a;
for (int i = 18; i >= 0; --i){
if(up[a][i] != up[b][i]){
a = up[a][i];
b = up[b][i];
}
}
return up[a][0];
}
int main(){
int t, n;
cin >> t;
while(t--){
cin >> n;
clear(n);
// re(dis);
// re(up);
// re(dep);
// adj->clear();
// cost->clear();
for (int i = 1; i < n; ++i){
int a, b, c;
cin >> a >> b >> c;
adj[a].push_back(b);
adj[b].push_back(a);
cost[a].push_back(c);
cost[b].push_back(c);
}
dfs(1, -1);
string s;
while(1){
cin >> s;
if(s == "DIST") {
int a, b;
cin >> a >> b;
cout << (dis[a] + dis[b] - 2 * dis[lca(a, b)]) << endl;
}
else if(s == "KTH"){
int a, b, k;
cin >> a >> b >> k;
if(k == 1){
cout << a << endl;
continue;
}
int lc = lca(a, b);
int d = dep[a] - dep[lc];
if(d + 1 >= k){
if(lc == a){
if(d + 1 == k) {
cout << b << endl;
continue;
}
else
k = d + 1 - k + 1;
}
k--;
for(int i = 18; i >= 0; --i){
if(k & (1 << i))
a = up[a][i];
}
cout << a << endl;
}
else {
k -= d;
--k;
d = dep[b] - dep[lc];
k = d - k;
for (int i = 18; i >= 0; --i){
if(k & (1 << i))
b = up[b][i];
}
cout << b << endl;
}
}
else
break;
}
}
return 0;
}边栏推荐
- 史上最易懂的f-string教程,收藏這一篇就够了
- How to Visualize Missing Data in R using a Heatmap
- HR wonderful dividing line
- (C语言)八进制转换十进制
- FastDateFormat为什么线程安全
- PyTorch搭建LSTM实现服装分类(FashionMNIST)
- 上传文件时,服务器报错:IOFileUploadException: Processing of multipart/form-data request failed. 设备上没有空间
- WSL 2 will not be installed yet? It's enough to read this article
- This article takes you to understand the operation of vim
- [untitled] how to mount a hard disk in armbian
猜你喜欢

Tas (file d'attente prioritaire)

H5, add a mask layer to the page, which is similar to clicking the upper right corner to open it in the browser

XSS labs master shooting range environment construction and 1-6 problem solving ideas

Pytorch builds LSTM to realize clothing classification (fashionmnist)

小程序链接生成

YYGH-BUG-04

Natural language processing series (III) -- LSTM

还不会安装WSL 2?看这一篇文章就够了

初始JDBC 编程

SVO2系列之深度濾波DepthFilter
随机推荐
Lekao: contents of the provisions on the responsibility of units for fire safety in the fire protection law
Addition, deletion, modification and query of MySQL table (Advanced)
Sort---
[QT] Qt development environment installation (QT version 5.14.2 | QT download | QT installation)
Experiment of connecting mobile phone hotspot based on Arduino and esp8266 (successful)
YYGH-BUG-04
Leetcode922 按奇偶排序数组 II
Those logs in MySQL
SSH automatically disconnects (pretends to be dead) after a period of no operation
Time format display
求16以内正整数的阶乘,也就是n的阶层(0=<n<=16)。输入1111退出。
Map and set
WSL 2 will not be installed yet? It's enough to read this article
(C语言)3个小代码:1+2+3+···+100=?和判断一个年份是闰年还是平年?和计算圆的周长和面积?
ES集群中节点与分片的区别
uniapp uni-list-item @click,uniapp uni-list-item带参数跳转
MSI announced that its motherboard products will cancel all paper accessories
Natural language processing series (III) -- LSTM
Pytorch builds LSTM to realize clothing classification (fashionmnist)
HOW TO ADD P-VALUES TO GGPLOT FACETS