当前位置: 首页 > news >正文

做淘宝门头的网站神宜建设公司官网

做淘宝门头的网站,神宜建设公司官网,做网站公司 郑州,做网站需要买什么模板题目:https://www.luogu.com.cn/problem/P3379 1 解题思路 求最近公共祖先,我们可以先用一个表f存储每个节点再跳1到若干跳可以到达的节点,另外我们用一个dep数组存储节点所处的深度(根节点的深度为1,这个用dfs去实…

模板题目:https://www.luogu.com.cn/problem/P3379

1 解题思路

求最近公共祖先,我们可以先用一个表f存储每个节点再跳1到若干跳可以到达的节点,另外我们用一个dep数组存储节点所处的深度(根节点的深度为1,这个用dfs去实现)。当一个询问来临,求点u和点v的最近公共祖先(假设u的深度大于v的深度),我们先让u来到和v同一深度的位置。之后看一下,如果来到同一深度时,两节点在同一位置,说明最近公共祖先是v。否则,就同时让u和v一起调到离最近公共祖先还差一步的深度,之后加一步就到最近公共祖先了。

2 进一步优化

洛谷的题目中提到:对于100%的数据,1≤N,M≤5×10^5。如果表f存的是各点每一跳能到达的节点,那么这样需要的空间很大,而且还会很浪费空间,因此,我们可以考虑使用ST表优化。
在这里,借用董晓老师的例子来说
在这里插入图片描述
图中有9个节点,用二维数组f存储下标的信息,f[6][2]表示节点6跳两跳到达的节点。在这里插入图片描述
想象一下如果是一个9个节点的斜二叉树的话,那就会占用9×9的空间,并且会有很多的0出现,比较浪费空间。因此我们可以使用ST表来实现。下标如果用二维数组f来存数据,f[3][2]表示节点3跳2的2次方(即跳4跳)跳后到达的节点,因为跳4跳已经超出根节点了,所以用0存储。在这里插入图片描述
如果我们想知道节点3跳3跳到达的节点怎么求呢?我们不妨把3拆分成2+1(二进制拆分),先让3跳2跳到达节点5,在看节点5跳1跳,即看f[5][0]到达的节点是1。
使用ST表存储可以把表格的列数大大减少,如果用N个节点,那么最多需要1+log2(N)列。在填表的时候,我们遵循从上到下从左到右的方向去填,先填f[1][0]到f[N][0],再填f[1][1]到f[N][1],…,最后填f[1][log2(N)+1]到f[N][log2(N)+1]。

3 变量及数组说明

  1. dep数组:存储节点的深度,根节点深度为1。
  2. f数组:存储ST表信息。
  3. 边使用链式前向星存储:
    ① head 数组:存储节点的一条出边
    ② to 数组:存储边的终点信息
    ③ nt 数组:存储要遍历的下一条边编号(一般来说,当前边和下一条边的起点是一样的)
  4. lg2数组:主要用于对层树做二进制拆分
  5. maxd:存储树的最大深度

4 AC代码

参考洛谷题解的代码:

#include<bits/stdc++.h>
using namespace std;
const int N=500005,M=N;
int n,m,s,lg2[N],f[N][22],head[N],ct,dep[N],maxd=-1; 
struct edge{int to,nxt;
}a[N<<2];
void add(int u,int v){a[++ct].to=v;a[ct].nxt=head[u];head[u]=ct;
}
void dfs(int x,int fa){f[x][0]=fa;dep[x]=dep[fa]+1;if(dep[x]>maxd) maxd=dep[x];for(int i=head[x];i;i=a[i].nxt){int tod=a[i].to;if(tod!=fa) dfs(tod,x);}
}
int lca(int u,int v){if(dep[u]<dep[v]) swap(u,v);// 先让u和v处于同一深度,深度差做二进制拆分while(dep[u]>dep[v]){u=f[u][lg2[dep[u]-dep[v]]];}if(u==v) return v;// 处于同一深度后,也是用二进制拆分,去让u和v再走一步祖先就相同。for(int i=lg2[dep[u]-1];i>=0;i--){if(f[u][i]!=f[v][i]){u=f[u][i],v=f[v][i];}}return f[u][0];
}
int main(){scanf("%d%d%d",&n,&m,&s);for(int i=2;i<=n;i++) lg2[i]=lg2[i/2]+1; //深度不会超过n,所以记录到n就可以了for(int i=1;i<n;i++){int u,v;scanf("%d%d",&u,&v);//这里要双向加边,便于dfs搜索,u和v谁是祖先要根据根节点dfs后来确定。add(u,v); add(v,u);}dfs(s,0);// 填ST表,要注意方向。具体要多少列,可以根据dfs之后的最大深度来定。for(int j=1;j<=lg2[maxd];j++){for(int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1];}for(int i=1;i<=m;i++){int u,v;scanf("%d%d",&u,&v);printf("%d\n",lca(u,v));}return 0;
}
http://www.dtcms.com/a/462928.html

相关文章:

  • 如何用dw做网站首页合肥大型网站建设
  • 网站怎样做优惠卷青岛当地的做公司网站的
  • 千年游戏智慧:文化的密码
  • 【AI读书系列-01】10秒沟通 --荒木真理子
  • 如何给网站做优化代码教学参考网站建设
  • 网站开发岗位群产品效果图怎么做出来的
  • 汉南网站建设怎么搭建网站
  • Dual Attention Network for Scene Segmentation 学习笔记
  • Linux 命令:umask
  • 蓝桥杯 填字母游戏
  • javascript开发app教程
  • 域名备案怎么关闭网站wordpress 页面下文章列表
  • SQL入门: HAVING用法全解析
  • 做卷闸门网站有用吗微信小程序商城怎样做
  • 买域名建网站价格青海网页设计
  • 大模型激活值所占用的内存与序列长度、模型维度的解析
  • 持续学习(Continual Learning):让AI像人类一样终身成长
  • 手机版网站推荐个人养老保险怎么交
  • kali制作钓鱼网站
  • seo整站优化方法wordpress跟随按钮怎么做
  • 海外建站服务平台涟水建设银行网站
  • 如何破解网站后台密码防水网站建设
  • 怎么做类似站酷的网站建设充值网站多钱
  • 如何把电脑改成服务器 做网站大连建站费用
  • 网站建设规模用什么形容西宁好的网站建设
  • c++26新功能—indirect<T>和polymorphic<T>
  • 网站建设方案文本模板网站服务器环境不支持mysql数据库
  • 网站建设费可以一次性冲费用吗手机免费建设网站制作
  • string的自主实现
  • usart波特率为9600和115200时,发送一句话所耗费的时间分别是多少