<题目链接>
题目大意:
给你一颗树的所有边,这些边是无向的,然后给你一段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