【蓝桥杯 LCA 差分】 砍树

news/2025/1/16 4:51:26/

在这里插入图片描述


题目分析:

这道题还是比较裸的一道书上差分的题目了
对于每一对标记点(x,y)
他们之间的路径就是 x − > L C A ( x , y ) − > y x->LCA(x,y)->y x>LCA(x,y)>y
这条路径上的每一条边都要经过。

那么对于一条边,什么时候砍掉这条边的时候,这几对点互相到达不了呢?
那就是这条边是这m条路径(一共m对点,每一对点都有一条路径)的公共边
也就是说这条边被经过了m次

因此,对于每一条边,我们用一个数组记录这条边被经过了几次
最后经过次数为m的边就是可以砍掉的边,最后取一个max即可

那么我们如何累加边经过的次数呢
借鉴数列差分的思想,我们利用树上差分去实现
对于一堆点 ( x , y ) (x,y) (x,y),我们令 s [ x ] + + , s [ y ] + + , s [ L c a ( x , y ) ] − = 2 s[x]++,s[y]++,s[Lca(x,y)]-=2 s[x]++,s[y]++,s[Lca(x,y)]=2
而后在树上做一遍前缀和即可


Code

#include<bits/stdc++.h>
using namespace std;const int N = 1e5+100;int fa[N][30];
int n,m;
struct Node{int y,Next,id;
}e[2*N];
int len , Linkk[N];
int s[N];
int d[N];void Insert(int x,int y,int id){e[++len] = (Node){y,Linkk[x],id};Linkk[x] = len;
}void Dfs(int x,int faa,int dd){d[x] = dd;for (int i = Linkk[x]; i; i = e[i].Next){int y = e[i].y;if (y == faa) continue;fa[y][0] = x;Dfs(y,x,dd+1);}
}void Pre(){for (int j = 1; (1 << j) < n; j++)for (int i = 1; i <= n; i++)if (fa[i][j-1] == -1) fa[i][j] = -1;else fa[i][j] = fa[fa[i][j-1]][j-1];
}int Lca(int x,int y){if (d[x] > d[y]) swap(x,y);for (int i = 0,dd = d[y]-d[x];dd; dd>>=1,i++)if (dd&1) y = fa[y][i];if (x == y) return x;for (int i = 29; i >= 0; i--)if (fa[x][i] != fa[y][i]) x = fa[x][i] , y =fa[y][i];return fa[x][0];
}void Plus(int x,int y){s[x]++ , s[y]++ , s[Lca(x,y)]-=2;
}void Dfss(int x,int faa){for (int i = Linkk[x]; i; i = e[i].Next){int y = e[i].y;if (y == faa) continue;Dfss(y,x);s[x]+=s[y];}
}int Max = -1;
void dfsM(int x,int faa){for (int i = Linkk[x]; i; i = e[i].Next){int y = e[i].y; if (y == faa) continue;if (s[y] == m) Max = max(Max,e[i].id);dfsM(y,x);}
}int main(){scanf("%d %d",&n,&m);for (int i = 1,x,y; i < n; i++)scanf("%d %d",&x,&y) , Insert(x,y,i) , Insert(y,x,i);Dfs(1,0,0); fa[1][0] = -1; Pre();for (int i = 1 , x,y; i <= m; i++)scanf("%d %d",&x,&y) , Plus(x,y);Dfss(1,0);dfsM(1,0);cout<<Max;return 0;
}

http://www.ppmy.cn/news/1246975.html

相关文章

SpringBoot集成MapStruct

引入mapstruct依赖 <dependency><groupId>org.mapstruct</groupId><artifactId>mapstruct</artifactId><version>${org.mapstruct.version}</version> </dependency>配置maven-compiler-plugin <build><plugins>&…

vue 通过ref调用router-view子组件的方法

由于用的vue2.7版本&#xff0c;但用了vue3 setup的语法&#xff1b; 注意&#xff1a;是vue2的template结构&#xff0c;vue3的setup语法&#xff1b;非这种情况需要举一反三。 处理方案&#xff1a; 1、对router-view加上ref template修改 直接对router-view加上ref&#x…

TIME_WAIT状态TCP连接导致套接字无法重用实验

理论相关知识可以看一下《TIME_WAIT相关知识》。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<arpa/inet.h> #include<sys/socket.h> #include<errno.h> #include<syslog.h> #inc…

为第一个原生Spring5应用程序添加上Log4J日志框架!

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

WPF创建进度条

使用wpf做一个原生的进度条&#xff0c;进度条上面有值&#xff0c;先看效果。 功能就是点击按钮&#xff0c;后台处理数据&#xff0c;前台显示处理数据的变化&#xff0c;当然还可以对进度条进行美化和关闭的操作&#xff0c;等待后台处理完毕数据&#xff0c;然后自动关闭。…

跨标签页通信的8种方式(下)

跨标签页通信是指在浏览器中的不同标签页之间进行数据传递和通信的过程。在传统的Web开发中&#xff0c;每个标签页都是相互独立的&#xff0c;无法直接共享数据。然而&#xff0c;有时候我们需要在不同的标签页之间进行数据共享或者实现一些协同操作&#xff0c;这就需要使用跨…

linux环境下对mysql操作

连接mysql操作 mysql -h ip -P端口 -u 用户 -p 密码 可以不写密码 mysql -h ip -P端口 -u 用户 -p 创建mysql里面的新用户 CREATE USER 用户名主机名 IDENTIFIED BY 密码; 授予用户权限 GRANT all ON 数据库名.表名 TO 用户名主机名; 可以再 all后面加 FLUSH PRIVIL…

docker限制容器内存的方法

在服务器中使用 docker 时&#xff0c;如果不对 docker 的可调用内存进行限制&#xff0c;当 docker 内的程序出现不可预测的问题时&#xff0c;就很有可能因为内存爆炸导致服务器主机的瘫痪。而对 docker 进行限制后&#xff0c;可以将瘫痪范围控制在 docker 内。 因此&#…