题意:给出一颗以1号节点为根的树,以及一个序列,问所给序列是不是所给树的一种BFS搜索顺序;
思路:把BFS顺序理解了,我的错误理解是只要深度相同的节点在一起就可以,忽略了其父节点访问顺序不同,同一深度的节点访问顺序也就不同这一问题;
如左图所示的树,其BFS搜索顺序有且仅有一下几种:
1->2->3->5->6->4
1->2->3->6->5->4
1->3->2->4->5->6
1->3->2->4->6->5
只有以上四种;而1->2->3->4->5->6就不行;
存下所有可能顺序,再去比较显然不可能实现,所以转换思路,根据所给出的序列去构造搜索序列,如果矛盾了,说明所给序列不是一种BFS搜索顺序;
具体看代码:
#include <bits/stdc++.h>
using namespace std;
vector<int> vec[200010];
int n;
int a[200010], inx[200010];//inx[i]表示i这个数在题目给出序列中的顺序;
vector<int> que, son;
int vis[200010];
//对son中的数按题目给出顺序排序;
bool cmp(int x, int y){
return inx[x]<inx[y];
}
void bfs(int r){
memset(vis, 0, sizeof(vis));
que.push_back(0);
que.push_back(r);
vis[r]=1;
for(int i=1; i<=n; i++){
//出现矛盾就NO;
if(a[i]!=que[i]){
cout << "No\n";
return;
}
int u=a[i];
son.clear();
//找出u的所有亲子节点,放入son,再对son排序;
for(int j=0; j<vec[u].size(); j++){
int v=vec[u][j];
if(vis[v]) continue;
son.push_back(v);
vis[v]=1;
}
sort(son.begin(), son.end(), cmp);
//按题目给出顺序构造que这样的搜索顺序;
for(int j=0; j<son.size(); j++){
que.push_back(son[j]);
}
}
cout << "Yes\n";
}
int main(){
scanf("%d", &n);
for(int i=1; i<n; i++){
int u, v;
scanf("%d%d", &u, &v);
vec[u].push_back(v);
vec[v].push_back(u);
}
for(int i=1; i<=n; i++){
scanf("%d", &a[i]);
inx[a[i]]=i;
}
bfs(1);
return 0;
}