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;
}
posted @   HappyBobb  阅读(12)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示