题目链接:http://codeforces.com/problemset/problem/1037/D
题目大意:
给出一棵树,询问一个序列是否可能为这棵树从节点1开始遍历的bfs序
题解:
对于每个节点,令其权值等于该元素在给序列中出现的位置
把每个节点的出边按照到达点的权值排序,来一次bfs得到一个bfs序,判断当前bfs序与给定序列是否相等即可
#include<algorithm> #include<cstring> #include<cstdio> #include<iostream> #include<vector> #include<queue> using namespace std; const int N=2e5+15; int n,m,s; int vis[N],giv[N],u[N],v[N],pos[N]; struct node { int y,val; }; bool operator < (node x,node y) {return x.val<y.val;} vector<node> g[N]; vector <int> p; inline int read() { char ch=getchar(); int s=0,f=1; while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();} while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();} return s*f; } void bfs() { queue <int> q; vis[1]=1; q.push(1); while (!q.empty()) { int k=q.front();q.pop(); p.push_back(k); for (int i=0;i<g[k].size();i++) { int y=g[k][i].y; if (vis[y]) continue; vis[y]=1; q.push(y); } } } int main() { n=read(); for (int i=1;i<n;i++) { u[i]=read();v[i]=read(); } for (int i=1;i<=n;i++) { giv[i]=read(); pos[giv[i]]=i; } for (int i=1;i<n;i++) { g[u[i]].push_back((node){v[i],pos[v[i]]}); g[v[i]].push_back((node){u[i],pos[u[i]]}); } for (int i=1;i<=n;i++) sort(g[i].begin(),g[i].end()); /*for (int i=1;i<=n;i++) { for (int j=0;j<g[i].size();j++) printf("%d ",g[i][j].val); printf(" "); }*/ bfs(); bool flag=1; for (int i=1;i<=n;i++) if (p[i-1]!=giv[i]) {flag=0;break;} if (flag) puts("Yes"); else puts("No"); return 0; }