题目大意:给定一个\(n(1\leq n\leq 2\cdot10^5)\)个节点的树的\(n-1\)条边和这棵树的一个\(BFS\)序\(a_1,a_2,\dots,a_n\),判断这个\(BFS\)序是否是一个从节点\(1\)开始的合法\(BFS\)序,若合法则输出\(Yes\),否则输出\(No\)

题目核心问题是判断给出的\(BFS\)序的合法性,根据\(BFS\)的定义,每个节点的所有子节点在加入队列时应当是连续的,且同深度的节点的子节点入队顺序应该整体与父节点入队顺序相同,不妨把每个节点的所有子节点在给定的\(BFS\)序列中的顺序看做连续的区间.

考虑到\(BFS\)序列不合法的原因有以下可能:

  • \(a_1\neq 1\)
  • 存在\(i,j\)满足\(i<j\)且\(dep[a_i]>dep[a_j]\)
  • 存在\(i,j\)满足\(i\neq j\)且\(a_i=a_j\)
  • 存在\(i,j\)满足\(i<j\)且\(a_i\)的某个子节点\(u\)与\(a_j\)的某个子节点\(v\)满足在\(BFS\)序中\(u\)在\(v\)之后

处理思路:对于给出的树先跑一边\(BFS\)求每个点的\(dep\)和其子节点在\(a\)序列中的位置区间,按照上述四种情况进行判断.

下面放\(AC\)代码\(\downarrow\downarrow\downarrow\)

  1. #include<cstdio>//CF1037D
  2. #include<iostream>
  3. #include<cstring>
  4. #include<string>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<cstdlib>
  8. #include<queue>
  9. using namespace std;
  10. const int N=200010,NN=400020;
  11. struct interval{
  12. int l,r;
  13. };
  14. int fr[N],edge[NN],nxt[NN],n,dep[N],vis[N],app[N],a[N],fa[N],dy[N];
  15. interval il[N];
  16. queue<int>q;
  17. void bfs(){
  18. q.push(1);
  19. dep[1]=1;
  20. int u;
  21. while(!q.empty()){
  22. u=q.front();
  23. vis[u]=1;
  24. q.pop();
  25. int now=fr[u],v;
  26. while(now){
  27. v=edge[now];
  28. if(!vis[v]){
  29. dep[v]=dep[u]+1;
  30. fa[v]=u;
  31. q.push(v);
  32. il[u].l=min(il[u].l,dy[v]);
  33. il[u].r=max(il[u].r,dy[v]);
  34. }
  35. now=nxt[now];
  36. }
  37. }
  38. }
  39. bool check(){
  40. if(a[1]!=1){
  41. return false;
  42. }
  43. int nowdep;
  44. for(int i=1;i<=n;i++){
  45. if(dep[a[i]]<nowdep||app[a[i]]){
  46. return false;
  47. }
  48. else{
  49. app[a[i]]=1;
  50. nowdep=dep[a[i]];
  51. }
  52. }
  53. int tr=1;
  54. for(int i=1;i<=n;i++){
  55. if(il[a[i]].l==200010){
  56. continue;
  57. }
  58. if(il[a[i]].l>tr){
  59. tr=il[a[i]].r;
  60. }
  61. else{
  62. return false;
  63. }
  64. }
  65. return true;
  66. }
  67. int main(){
  68. scanf("%d",&n);
  69. int u,v;
  70. for(int i=1;i<=n;i++){
  71. il[i].l=200010;
  72. il[i].r=0;
  73. }
  74. for(int i=1;i<n;i++){
  75. int j=i+n;
  76. scanf("%d%d",&u,&v);
  77. edge[i]=v;
  78. nxt[i]=fr[u];
  79. fr[u]=i;
  80. edge[j]=u;
  81. nxt[j]=fr[v];
  82. fr[v]=j;
  83. }
  84. for(int i=1;i<=n;i++){
  85. scanf("%d",&a[i]);
  86. dy[a[i]]=i;
  87. }
  88. bfs();
  89. if(check()){
  90. printf("Yes\n");
  91. return 0;
  92. }
  93. else{
  94. printf("No\n");
  95. return 0;
  96. }
  97. return 0;
  98. }

Codeforces | CF1037D 【Valid BFS?】的更多相关文章

  1. 题解 CF1037D 【Valid BFS?】

    不管怎么说,这都不是道紫题吧... 这里采用的思想有点类似轻重链剖分. 我们按照每个节点在序列里面出现的顺序,把每一个节点连出去的边都排一个序. 这样(如果序列没错)肯定会按照序列的方式遍历完全图. ...

  2. HDU 5925 Coconuts 【离散化+BFS】 (2016CCPC东北地区大学生程序设计竞赛)

    Coconuts Time Limit: 9000/4500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Su ...

  3. hdu 1026 Ignatius and the Princess I【优先队列+BFS】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1026 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  4. 【openjudge】【搜索(bfs)】P4980拯救行动

    [描述:] 公主被恶人抓走,被关押在牢房的某个地方.牢房用N*M (N, M <= 200)的矩阵来表示.矩阵中的每项可以代表道路(@).墙壁(#).和守卫(x). 英勇的骑士(r)决定孤身一人 ...

  5. CodeVS 1226 倒水问题【DFS/BFS】

    题目描述 Description 有两个无刻度标志的水壶,分别可装 x 升和 y 升 ( x,y 为整数且均不大于 100 )的水.设另有一水 缸,可用来向水壶灌水或接从水壶中倒出的水, 两水壶间,水 ...

  6. Codeforces 176B【计数DP】

    题意: 给你两个串s1,s2和一个K, 有一种操作是在一个串切开然后交换位置, 问s1有多少种方法经过K次这样的操作变成s2: 思路: (从来没接触过计数DP...还是太菜...参考了[大牛blog] ...

  7. 【DFS/BFS】NYOJ-58-最少步数(迷宫最短路径问题)

    [题目链接:NYOJ-58] 经典的搜索问题,想必这题用广搜的会比较多,所以我首先使的也是广搜,但其实深搜同样也是可以的. 不考虑剪枝的话,两种方法实践消耗相同,但是深搜相比广搜内存低一点. 我想,因 ...

  8. HDU 2102 A计划【三维BFS】

    A计划 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissio ...

  9. UVA 11624 Fire!【两点BFS】

    Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the m ...

随机推荐

  1. Python_架构、同一台电脑上两个py文件通信、两台电脑如何通信、几十台电脑如何通信、更多电脑之间的通信、库、端口号

    1.架构 C/S架构(鼻祖) C:client  客户端 S:server  服务器 早期使用的一种架构,目前的各种app使用的就是这种架构,它的表现形式就是拥有专门的app. B/S架构(隶属于C/ ...

  2. 06_Hadoop分布式文件系统HDFS架构讲解

    mr  计算框架 假如有三台机器 统领者master 01  02  03  每台机器都有过滤的应用程序 移动数据 01机== 300M  >mr 移动计算  java程序传递给各个机器(mr) ...

  3. MYSQL 三元 函数

    mysql函数之流程控制-FreeOAhttp://www.freeoa.net/osuport/db/mysql-control-fun_2143.html mysql如何利用三元算法判断数字奇偶性 ...

  4. Python3练习题 006 冒泡排序

    import random a = [random.randint(1,100) for i in range(10)]def bu(target): length = len(target) whi ...

  5. 11 The superlative

    1 最高级用来表明三个或更多事物之间的关系.最高级是通过在形容词之前加 "the" 并在之后加 "-est",或在形容词之前加 "the most&q ...

  6. Socket和ObjectOutputStream问题

    用到Socket序列化对象网络传输时ObjectOutputStream一直刷新连接 用户代码 package com.jachs.ladflower.ladflower; import java.n ...

  7. php redis常用方法代码例子

    1,connect 描述:实例连接到一个Redis.参数:host: string,port: int返回值:BOOL 成功返回:TRUE;失败返回:FALSE 示例: <?php $redis ...

  8. 如何抓取电商的数据 & Python

    如何抓取电商的数据 & Python https://www.zhihu.com/question/40720286 https://www.zhihu.com/question/382455 ...

  9. onkeyup+onafterpaste 只能输入数字和小数点--转载

    JS判断只能是数字和小数点 1.文本框只能输入数字代码(小数点也不能输入)<input onkeyup="this.value=this.value.replace(/\D/g,'') ...

  10. Introduction to Dynamic SQL

    The idea of using dynamic SQL is to execute SQL that will potentially generate and execute another S ...