题目大意:
  • 给定两颗节点编号都为1~n的树A和B,每个节点都有一个权重。
  • 再给K个节点编号 ,求在两颗树中删除K中任意一个节点后剩余的k-1个节点中最近公共祖先节点的权重A中大于B课可行方案的数量。
解题思路:
  • 首先我们要先了解一下LCA算法,LCA算法就是能在log(n) 的时间内求出两个点的最近公共祖先节点。

  • LCA 算法首先要预处理出来两个数组,f[i,j]表示i这个节点往上走2的j次方所能走到的节点,depth[i] 表示i这个节点的深度。求f[i,j]可以用倍增的思想来做,depth数组可以用宽搜来求出每个点的深度。

  • 我们如果要求K个点最近公共祖先节点,只需要求这K个点中深度最大和深度最小的这两个节点的最小公共祖先节点。

  • 然后我们可以重载一下sort函数,把这K个节点按照深度从小到大排好序;然后依次枚举我们要删除的节点的编号,只要我们选择删除的不是最小或最大的深度的节点我们就只需要求最小和最大深度的最近公共祖先节点然后比较它们的权重即可;如果删除的是最小的或最大深度的节点,那我们就退一步,我们就可以选第二小或者第二大深度的节点然后按照上述方法求出即可。

完整代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100010,M=N*2;//邻接表储存树A,B;
int ha[N],ea[M],nea[M],idxa;
int hb[N],eb[M],neb[M],idxb;//LCA 倍增需要用到的数组
int  fa[N][31],deptha[N];
int  fb[N][31],depthb[N];
//队列
int qa[N],qb[N];
//权重
int wa[N],wb[N];
// 关键点
int ka[N],kb[N];int stA[N],stB[N];
int n,m;
int cnt=0;void bfs(int root,int u)
{if(u==1){memset(deptha,0x3f,sizeof deptha);int qa[N];int hh=0,tt=0;qa[0]=root; deptha[0]=0,deptha[root]=1;stA[root]=1;int cnt=1;while(hh<=tt){int t=qa[hh++];for(int i=ha[t];i!=-1;i=nea[i]){int j=ea[i];if(deptha[j]>deptha[t]+1){deptha[j]=deptha[t]+1;qa[++tt]=j;fa[j][0]=t;stA[j]=++cnt;for(int k=1;k<=30;k++){fa[j][k]=fa[fa[j][k-1]][k-1];}}}}}else{memset(depthb,0x3f,sizeof depthb);int hh=0,tt=0;qb[0]=root;depthb[0]=0,depthb[root]=1;stB[root]=1;int cnt=1;while(hh<=tt){int t=qb[hh++];for(int i=hb[t];i!=-1;i=neb[i]){int j=eb[i];if(depthb[j]>depthb[t]+1){depthb[j]=depthb[t]+1;qb[++tt]=j;fb[j][0]=t;stB[j]=++cnt;for(int k=1;k<=30;k++){fb[j][k]=fb[fb[j][k-1]][k-1];}}}}}}void  add(int a,int b,int u)
{if(u==0){ea[idxa]=b;nea[idxa]=ha[a];ha[a]=idxa++;}else{eb[idxb]=b;neb[idxb]=hb[a];hb[a]=idxb++;}
}bool cmpA(int a,int b)
{return stA[a]<stA[b];
}bool cmpB(int a,int b)
{return stB[a]<stB[b];
}int lcaA(int x, int y) {if (deptha[x] > deptha[y]) swap(x, y);int tmp = deptha[y] - deptha[x], ans = 0;for (int j = 0; tmp; ++j, tmp >>= 1)if (tmp & 1) y = fa[y][j];if (y == x) return x;for (int j = 30; j >= 0 && y != x; --j) {if (fa[x][j] != fa[y][j]) {x = fa[x][j];y = fa[y][j];}}return fa[x][0];
}int lcaB(int x, int y) {if (depthb[x] > depthb[y]) swap(x, y);int tmp = depthb[y] - depthb[x], ans = 0;for (int j = 0; tmp; ++j, tmp >>= 1)if (tmp & 1) y = fb[y][j];if (y == x) return x;for (int j = 30; j >= 0 && y != x; --j) {if (fb[x][j] != fb[y][j]) {x = fb[x][j];y = fb[y][j];}}return fa[x][0];
}int main()
{ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>m;memset(ha,-1,sizeof ha);memset(hb,-1,sizeof hb);for(int i=1;i<=m;i++) {cin>>ka[i];kb[i]=ka[i];}for(int i=1;i<=n;i++){cin>>wa[i];}for(int i=1;i<=n-1;i++){int b;cin>>b;add(i+1,b,0);add(b,i+1,0);}for(int i=1;i<=n;i++) cin>>wb[i];for(int i=1;i<=n-1;i++){int b;cin>>b;add(i+1,b,1);add(b,i+1,1);}bfs(1,1);bfs(1,2);sort(ka+1,ka+1+m,cmpA);sort(kb+1,kb+1+m,cmpB);int ans=0;for(int i=1;i<=m;i++){int xa=ka[1],ya=ka[m];int xb=kb[1],yb=kb[m];if(i==1) xa=ka[2];else if(i==m) ya=ka[m-1];if(xb==ka[i]) xb=kb[2];else if(yb==ka[i]) yb=kb[m-1];int lcaa=lcaA(xa,ya);int lcab=lcaB(xb,yb);if(wa[lcaa]>wb[lcab]) ans+=1;}cout<<ans<<endl;return 0;}

牛客暑期训练营三 A题相关推荐

  1. 2020 牛客暑期训练营补题(第一场)

    暑假还是不能摸鱼了,尽量每天补一道题. 这里大部分的补题应该都是参考了大佬的题解,所以如果有大佬看到了自己的解法,请多多包涵. 第一场 A题 题目描述 题目思路 代码 F题 I题 J题 A题 题目描述 ...

  2. 2021牛客暑期训练营1

    A: Alice and Bob 大致题意:有两堆石头,一堆为n一堆为m,每个人每次可以从一堆中拿k块石头,另一堆中拿s*k块(s>=0),Alice先拿,无法执行操作的人属输掉. 输入描述:有 ...

  3. 2019牛客暑期多校训练营(第三场)H.Magic Line

    2019牛客暑期多校训练营(第三场)H.Magic Line 题目链接 题目描述 There are always some problems that seem simple but is diff ...

  4. 2020牛客暑期多校训练营(第三场)A.Clam and Fish

    2020牛客暑期多校训练营(第三场)A.Clam and Fish 题目链接 题目描述 There is a fishing game as following: The game contains ...

  5. 2021牛客暑期多校训练营2,签到题CDFKI

    2021牛客暑期多校训练营2 题号 标题 已通过代码 通过率 团队的状态 A Arithmetic Progression 点击查看 6/72 未通过 B Cannon 点击查看 34/104 未通过 ...

  6. 2021牛客暑期多校训练营1, 签到题DFBG

    2021牛客暑期多校训练营1 题号 标题 已通过代码 通过率 团队的状态 A Alice and Bob 点击查看 1365/5586 通过(博弈论-打表) B Ball Dropping 点击查看 ...

  7. “蔚来杯“2022牛客暑期多校训练营9 补题题解(A、B、G、E)

    "蔚来杯"2022牛客暑期多校训练营9 A Car Show B Two Frogs G Magic Spells E Longest Increasing Subsequence ...

  8. 【训练题66:状压暴力 | 子集dp】Greater Integer, Better LCM | 2021牛客暑期多校训练营5

    题意 Greater Integer, Better LCM | 2021牛客暑期多校训练营5 给你 a,b,ca,b,ca,b,c ,你需要找到一对 x,yx,yx,y ,满足: lcm(a+x,b ...

  9. 题解 | Coffee Chicken-2019牛客暑期多校训练营第十场B题

    题目来源于牛客竞赛:https://ac.nowcoder.com/acm/contest/discuss 题目描述: 输入描述: 输出描述: 示例1: 题解: 代码: #!/usr/bin/pyth ...

最新文章

  1. 的python如何降级_提效降本:蚂蚁金服如何用融合计算改造在线机器学习
  2. 定义一个有参宏判断一个字符是否在0~9之间
  3. BCH的去中心化理念自治
  4. 美团mysql 闪回_MyFlash——美团点评的开源MySQL闪回工具
  5. linux命令:xargs
  6. poj 3150 Cellular Automaton(迷糊,但原理是用的快速幂)
  7. IdeaVim插件使用技巧
  8. boost::math::filters::daubechies_scaling_filter用法的测试程序
  9. 使用OpenCV,Keras和Tensorflow构建Covid19掩模检测器
  10. python保存为xlsb_Read XLSB File in Pandas Python
  11. tesseract4.0.0 中文语言包_一份TensorFlow2.0中文教程
  12. 二叉树两节点距离java,求二叉树中两个节点的最远距离
  13. 突破XXX,冲上Google+
  14. 蒙提霍尔问题(三门问题,概率论)C语言验证
  15. PMP/CAPM/PgMP/ACP考试报名资格
  16. SpringBoot+MyBatis(动态数据源/分布式事务XA(Atomikos))
  17. 如何向DMOZ目录提交网站?
  18. 经济数据预测 | Python实现CNN-LSTM股票价格预测时间序列预测
  19. ESP8266之TFT_eSPI库的自定义字体
  20. FileManager 文件管理器

热门文章

  1. 2023年中国地质大学(北京) 机械考研考情上岸前辈初复试备考经验
  2. 学计算机的机械硕士好找工作吗,学机械的为啥转行特别多?网友:一言难尽,就业率高,质量不高...
  3. 高校教务系统需求文档
  4. CDUT新生赛wp misc (杂项
  5. 掌握未来趋势的UI设计成长之路
  6. 2021年通州中学高考成绩查询,2021北京通州中考分数线是多少
  7. 荣耀猎人游戏本V700具备哪些方面的优势特点?
  8. 引入pagehelper 追加limite 问题解决
  9. 存储带表情的微信昵称
  10. 为什么每个商场都在卖新能源车,特斯拉却频频撤店?