题意:给出你一棵树,然后给出一个遍历顺序,问:该序列是否为这棵树的可能BFS序。你只需考虑从1开始遍历的情况。
思路:本来自己写的想着是只要当前这个点的步数大于等于前一个点就可行,但其实不对,这个条件不充分。
是有效的bfs序的充分的条件应该是:层数不降且父节点顺序不降。
看到前几的大佬代码更简洁,只是按照进队列的顺序排了一个序,这样就可以我们保证自己写的BFS序最可能是符合所给顺序的BFS序了。如果这样都不行,哪一定不行。感性理解感性理解。
AC代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 3e5;
vector<int> G[N];
int a[N],b[N],vis[N],cur[N];
int main(int argc, char const *argv[])
{
int n,x,y;
cin >> n;
for(int i = 1; i < n; ++i){
scanf("%d %d", &x, &y);
--x; --y;
G[x].push_back(y);
G[y].push_back(x);
}
for(int i = 0; i < n; ++i){
cin >> a[i];
--a[i];
b[a[i]] = i;
}
for(int i = 0; i < n; ++i){
sort(G[i].begin(), G[i].end(), [&](int x, int y){
return b[x] < b[y];
});
}
int step = 0;
queue<int> que;
que.push(0);
while(!que.empty()){
int pos = que.front(); que.pop();
if(vis[pos]) continue;
vis[pos] = 1;
cur[pos] = step++;
for(int i = 0; i < (int)G[pos].size(); ++i){
int u = G[pos][i];
if(!vis[u]){
que.push(u);
}
}
}
bool ok = 1;
for(int i = 0; i < n; ++i){
if(cur[i] != b[i]){
ok = 0;
break;
}
}
if(ok) puts("Yes");
else puts("No");
return 0;
}