题解 CF1037D 【Valid BFS?】
我好菜啊qwq
我在赛场上想到了一个奇怪的方法,然后巧妙而又完美地避开了简单的正解qwq
题目意思就不赘述了,我当时非常
然后就很愉快地
接着,我茅塞顿开,发现自己
看着代码,因为我写了个
(敲黑板)我发现自己的代码之所以
此时,虽然满足后面深度
对着这个错误的,假的代码,我想出了这么个东西:
因为先访问的节点的子节点(直系子节点,以后亦是这个意思)也是先访问的,所以这个好像也是个队列。
所以,我们可以开一个队列,来模拟这个事情。有人就说,搞什么啊,不又回到基本的
举个例子,
在这个图中,如果
很简单,我们边做边判断。
在此时,入队的一定是
但怎么把不同节点的新一层子节点区分出来呢?还要写一大堆的东西保留分界线吗?
我当时脑子一抽,想到了个玩意儿,叫
把每个节点的子节点预处理出来,存在一个
然后当我们要判有没有
但删掉的复杂度是不对的,因为
那还要删除干嘛,直接搞个计数器累加一下看看等不等于
然后,我开心地写完了,然后开心地交了上去,
我又开心地发现,我的
然后,我又开心地改掉了,然后开心地交了上去,又
我又开心地发现,如果堆了一些叶子节点的
然后就好了。
代码:(42398197)
#pragma comment (linker,"/STACK:1024000000")
#pragma GCC optimize(2)
#pragma GCC target(arch=corie7-acx)
#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> E[200001];
vector<int> son[200001];
int fa[200001];
void dfs (int u)
{
for (auto v:E[u])
{
if (v==fa[u]) continue;
son[u].push_back(v);
fa[v]=u;
dfs(v);
}
return;
}
int u,v;
int x,m;
queue<vector<int>> q;
vector<int> t;
int num,sum;
vector<int>::iterator it;
int main()
{
scanf("%d",&n);
for (int i=1;i<=n-1;i++)
{
scanf("%d%d",&u,&v);
E[u].push_back(v);
E[v].push_back(u);
}
dfs(1);
scanf("%d",&x);
if (x!=1) return puts("No"),0;
q.push(son[1]);
t=q.front();
sort(t.begin(),t.end());
for (int i=2;i<=n;i++)
{
scanf("%d",&x);
while (sum==t.size())
{
q.pop();
if (q.empty()) return puts("No"),0;
t=q.front();
sort(t.begin(),t.end());
sum=0;
}
it=(lower_bound(t.begin(),t.end(),x)+1);
//printf("%d ",x);
num=it-t.begin();
//printf("%d:%d\n",num,t[num-1]);
if (x!=t[num-1]) return puts("No"),0;
sum++;
q.push(son[x]);
}
printf("Yes");
return 0;
}
这题细节好多啊(或许是我写的作死吧)。