<题目链接>
题目大意:
给你一颗树的所有边,这些边是无向的,然后给你一段BFS序列,BFS都以1为根节点,判断这段BFS序列是否合法。
解题分析:
就是模拟BFS,某个父亲节点的所有子节点必然是连续一段出现的(如果该BFS序合法的话),所以每次从队列中弹出节点的时候,就将对应位置连续的所有儿子全部标记,如果有儿子不是连续的出现在对应位置,则之后永远不会被标记到。
#include <bits/stdc++.h> using namespace std; const int N = 2e5+5; int n,vis[N],fa[N],a[N]; map<int,int>mp[N]; template<typename T> inline void read(T&x){ x=0;int f=1;char c=getchar(); while(c<'0' || c>'9'){ if(c=='-')f=-1;c=getchar(); } while(c>='0' && c<='9'){ x=x*10+c-'0';c=getchar(); } x*=f; } void bfs(){ queue<int>q; q.push(a[1]);int loc=2; while(!q.empty()){ int u=q.front();q.pop(); vis[u]=1; while(mp[u][a[loc]]){ //就是模拟BFS,将它接下来的儿子全部塞入队列,如果u的儿子不是连续的出现在这些位置,则永远不可能被标记到 q.push(a[loc]); loc++; } } } int main(){ read(n); for(int i=1;i<n;i++){ int u,v;read(u);read(v); mp[u][v]=1;mp[v][u]=1; } for(int i=1;i<=n;i++)read(a[i]); if(a[1]!=1)return puts("No"),0; bfs(); for(int i=1;i<=n;i++) if(!vis[i])return puts("No"),0; puts("Yes"); }