CF1037D Valid BFS?
题意
给定一棵树和一个序列,问这个序列是否是一个可能的 BFS 序列。
做法
我的代码应该是非常长的了。
可以考虑模拟,从根节点开始往下,每层判断上一层是否所有结点都遍历过,以及判断出队顺序是否有误,具体可以看代码,欢迎 hack。
复杂度应该为线性。
对于 BFS 序列里每一个点,判断之前的点最后一层是否已满,如果未满,显然应该继续填。
此外还应该判断出队顺序。
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, a[N], fa[N], dep[N];
vector<int> G[N];
int id[N], cnt[N];
void dfs2(int u, int fa, int depth)
{
dep[u] = depth;
for (int i = 0; i < G[u].size(); i++)
{
int j = G[u][i];
if (j == fa) continue;
dfs2(j, u, depth + 1);
}
}
void dfs(int u, int Fa)
{
fa[u] = Fa;
for (int i = 0; i < G[u].size(); i++)
{
int j = G[u][i];
if (j == Fa) continue;
dfs(j, u);
}
}
struct Node
{
int val, cnt;
Node(int _v, int _c): val(_v), cnt(_c){}
};
deque<Node> mp[N];
bool bfs()
{
memset(id, -1, sizeof id);
queue<int> q;
q.push(1);
for (int i = 1; i <= n; i++)
{
cnt[dep[i]]++;
}
mp[1].push_front(Node(1, G[1].size()));
for (int i = 0; i < G[1].size(); i++)
{
int j = G[1][i];
if (j != fa[1])
{
id[j] = 1;
}
}
cnt[1] = 0;
int last = 1;
for (int i = 2; i <= n; i++)
{
int v = a[i];
if (id[v] == -1)
{
//printf("1331\n");
return false;
}
q.push(v);
//id[v] = -1;
for (int j = 0; j < G[v].size(); j++)
{
int k = G[v][j];
if (k != fa[v])
{
id[k] = v;
}
}
if (mp[last].empty()) last = dep[v];
if (dep[v] != last)
{
if (dep[v] > last + 1)
{
//if (n > 100) printf("%d\n", 12312);
return false;
}
if (dep[v] == last + 1)
{
//printf("%d %d %d\n", v, mp[last].front().val, mp[last].front().cnt);
if (cnt[last])
{
//printf("1333\n");
return false;
}
if (mp[last].front().cnt <= 0)
{
mp[last].pop_front();
}
if (id[v] != mp[last].front().val)
{
//printf("1333\n");
return false;
}
mp[last][0].cnt--;
if (mp[last].front().cnt <= 0)
{
mp[last].pop_front();
}
if (mp[last].empty()) last = dep[v];
cnt[dep[v]]--;
}
}
else
{
cnt[last]--;
}
if (mp[last].empty()) last = dep[v];
id[v] = -1;
if (G[v].size() - 1) mp[dep[v]].push_back(Node(v, G[v].size() - 1));
}
return true;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i < n; i++)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs(1, -1);
dfs2(1, -1, 1);
set<int> p;
for (int i = 1; i <= n; i++) scanf("%d", &a[i]), p.insert(a[i]);
if (a[1] != 1 || p.size() != n)
{
printf("No\n");
return 0;
}
if (bfs()) printf("Yes\n");
else printf("No\n");
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现