题目大意:给定一个\(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\)

#include<cstdio>//CF1037D
#include<iostream>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<queue> using namespace std; const int N=200010,NN=400020; struct interval{
int l,r;
}; int fr[N],edge[NN],nxt[NN],n,dep[N],vis[N],app[N],a[N],fa[N],dy[N]; interval il[N]; queue<int>q; void bfs(){
q.push(1);
dep[1]=1;
int u;
while(!q.empty()){
u=q.front();
vis[u]=1;
q.pop();
int now=fr[u],v;
while(now){
v=edge[now];
if(!vis[v]){
dep[v]=dep[u]+1;
fa[v]=u;
q.push(v);
il[u].l=min(il[u].l,dy[v]);
il[u].r=max(il[u].r,dy[v]);
}
now=nxt[now];
}
}
} bool check(){
if(a[1]!=1){
return false;
}
int nowdep;
for(int i=1;i<=n;i++){
if(dep[a[i]]<nowdep||app[a[i]]){
return false;
}
else{
app[a[i]]=1;
nowdep=dep[a[i]];
}
}
int tr=1;
for(int i=1;i<=n;i++){
if(il[a[i]].l==200010){
continue;
}
if(il[a[i]].l>tr){
tr=il[a[i]].r;
}
else{
return false;
}
}
return true;
} int main(){
scanf("%d",&n);
int u,v;
for(int i=1;i<=n;i++){
il[i].l=200010;
il[i].r=0;
}
for(int i=1;i<n;i++){
int j=i+n;
scanf("%d%d",&u,&v);
edge[i]=v;
nxt[i]=fr[u];
fr[u]=i;
edge[j]=u;
nxt[j]=fr[v];
fr[v]=j;
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
dy[a[i]]=i;
}
bfs();
if(check()){
printf("Yes\n");
return 0;
}
else{
printf("No\n");
return 0;
}
return 0;
}

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]解决Windows下安装第三方插件报错:UnicodeDecodeError: 'ascii' codec can't decode byte 0xcb in position 0:

    系统:win7IDE:pycharm Python版本:2.7 安装第三方插件是报错:  报错原因与编码有关,pip把下载的临时文件存放在了用户临时文件中,这个目录一般是C:\Users\用户名\Ap ...

  2. c++局部变量在外可用的方法

    C++的局部变量在作用域结束后,一般都会被回收.如下面这段代码 map<a*, b*> _map; void fun() { a _a; b _b; _map[&_a] = &am ...

  3. PAT 7-14 公路村村通

    https://pintia.cn/problem-sets/1111189748004499456/problems/1111189831248850957 现有村落间道路的统计数据表中,列出了有可 ...

  4. Linux 典型应用之常用命令

    软件操作相关命令 软件包管理 (yum) 安装软件 yum install xxx(软件的名字) 如 yum install vim 卸载软件 yum remove xxx(软件的名字) 如 yum ...

  5. Linux系统中常用的命令汇总

    日常开发,上线的服务器系统一般都是Linux系统,所以,熟练的掌握常用的命令操作就尤其的重要了 1) 查看某个服务的运行情况 (例如Redis) ps -ef | grep redis //e-显示程 ...

  6. nodejs配置nginx 以后链接mongodb数据库

    服务器 :windows server2008 R2 反向代理 :nginx 1.15.1 for window 64位 数据库:mongodb 4 64位 使用框架express 首先下载nodej ...

  7. 面试题(校招java)

    1:linux线程和进程的区别? 进程是程序执行时的一个实例,即它是程序已经执行到课中程度的数据结构的汇集.从内核的观点看,进程的目的就是担当分配系统资源(CPU时间.内存等)的基本单位. 线程是进程 ...

  8. oracle计算时间常用函数

    --ddd:一年中的第几天 select to_char(sysdate,'ddd') from dual --d:一周中的第几天 星期天是第一天 所以要-1select to_char(sysdat ...

  9. vue ajax

    局部get: this.$http.get(url,{param:jsonData}).then(successCallback,failCallBack) 局部post: this.$http.po ...

  10. spring boot web开发 简单的增删改查和spring boot 自带的Junit测试 案例

    创建 web项目 配置pom.xml文件   ------相当于jar包 配置application.yml -----配置文件(spring数据库连接.server服务.logging日志等) 创建 ...