Codeforces 1037 D【BFS】

<题目链接>

题目大意:

给你一颗树的所有边,这些边是无向的,然后给你一段BFS序列,BFS都以1为根节点,判断这段BFS序列是否合法。

解题分析:

就是直接对给定的BFS序跑一遍BFS,如果某些数字排序不符合BFS序,那么它就不会被遍历到,具体原因见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<map>

using namespace std;
int q[200005];
bool vis[200005];
int a[200005];
map<int,int>mp[200005];
void bfs()
{
    int qh=0,qt=0;
    q[qt++]=1; vis[1]=1; int tmp=1;
    while(qh<qt)
    {
        int u=q[qh++];
        while(mp[u][a[tmp+1]]==1) {   //如果这两个是父子节点关系的话,a[tmp+1]就能被推入队列,并被标记,否则的话,就会  
        //更换父亲节点,因此,如果当以某一个节点为父亲节点时(即此处的u)如果它接下来的连续子节点中插入了不符合BFS序的节  
        //点,那么就会更换父节点,所以那些在这些插入的节点后的本来属于u的一些子节点将永远不会被推入队列、打上标记.  
           q[qt++]=a[++tmp];
           vis[a[tmp]]=1;                                                   
        }
    }
}
int main ()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        int u,v;
        scanf("%d%d",&u,&v);
        mp[u][v]=1; mp[v][u]=1;
    }
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    if(a[1]!=1) return printf("NO\n"),0;    //题意,1必须是根节点  
    bfs();
    for(int i=1;i<=n;i++)
    {
        if(!vis[i]) return printf("NO\n"),0;
    }
    printf("YES\n");
    return 0;
}

2018-09-05

猜你喜欢

转载自www.cnblogs.com/00isok/p/9595413.html