题意:给一个树和一个bfs序,并保证从节点1出发,判bfs序是否合法。
思路:双指针,在bfs序上从左往右遍历。慢指针指向当前节点u,快指针指向当前节点应该访问的节点的位置。 然后设两个集合,一个集合存储在当前节点上应该访问的节点,另一个存储在当前节点上实际访问的节点,然后遍历即可。
总结:一开始想的是对每个节点求一个深度,然后保证节点的深度非递减排序就行了,但是这个算法有个bug,就是如果同层节点的访问顺序不同,那么下一层的节点访问顺序也不同,即使它们的深度都是一样的,这种深度判定的方法漏掉了这种情况。
void solve(){
int n;
cin >> n;
vector<vector<int>> al(n);
for (int i = 0; i < n - 1; ++i){
int u, v;
cin >> u >> v;
u --;
v --;
al[u].emplace_back(v);
al[v].emplace_back(u);
}
vector<int> order(n);
for (int i = 0; i < n; ++i){
int cur;
cin >> cur;
cur --;
order[i] = cur;
}
vector<bool> vis(n);
vis[0] = 1;
bool ok = true;
int i, j;
for (i = 0, j = 1; i < n; ){
int u = order[i];
set<int> should_vis;
for (const int& v : al[u]){
if (vis[v] == false){
should_vis.insert(v);
}
}
set<int> has_vis;
for (int s = j; s < j + int(should_vis.size()); ++s){
has_vis.insert(order[s]);
}
if (has_vis != should_vis){
ok = false;
break;
}
for (const int& v : should_vis){
vis[v] = true;
}
i ++;
j += int(should_vis.size());
}
cout << (ok ? "Yes" : "No") << '\n';
}
标签:Manthan,rated,cur,int,al,should,vis,Div,节点
From: https://www.cnblogs.com/yxcblogs/p/18165078