$des$
一个 n 个点 m 条边的无向连通图从 1 号点开始 bfs,可能得到的 bfs 序有很多,
取决于出边的访问顺序。现在给出一个 1 到 n 的排列,判断是否可能是一个 bfs 序。
$sol$
对于每个节点,令其权值为在给定序列中的位置。
然后从 1 号点开始正常的 bfs,出边的访问顺序按照权值从小到大访问。
最后将得到的 bfs 序与给定序列比较,若完全一致则是合法的。
$code$
#include <bits/stdc++.h> using namespace std; #define gc getchar() inline int read() { int x = 0; char c = gc; while(c < '0' || c > '9') c = gc; while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc; return x; } #define LL long long #define Rep(i, a, b) for(int i = a; i <= b; i ++) const int N = 2e5 + 10; int A[N]; int n; vector <int> V[N]; int W[N]; int B[N], js; bool use[N]; int ls[N], len; bool Cmp(int a, int b) { return W[a] < W[b]; } void Bfs(int s) { queue <int> Q; use[s] = 1; Q.push(s); while(!Q.empty()) { int tp = Q.front(); B[++ js] = tp; Q.pop(); len = 0; int S = V[tp].size(); Rep(i, 0, S - 1) { int v = V[tp][i]; if(use[v]) continue; use[v] = 1; ls[++ len] = v; } sort(ls + 1, ls + len + 1, Cmp); Rep(i, 1, len) Q.push(ls[i]); } } int main() { n = read(); Rep(i, 1, n - 1) { int u = read(), v = read(); V[u].push_back(v), V[v].push_back(u); } Rep(i, 1, n) A[i] = read(); Rep(i, 1, n) W[A[i]] = i; Bfs(1); Rep(i, 1, n) { if(A[i] != B[i]) { cout << "No"; return 0; } } cout << "Yes"; return 0; }