Manthan, Codefest 18 (rated, Div. 1 + Div. 2) D Valid BFS?(BFS)

Description:

给出一个以1为根的节点编号为1到n的树,再给出一个序列,问这个序列是不是有可能为该树的BFS序列

Input:

n,和n-1条树边以及一个带判断的序列

Output:

yes or no

Analysis:

BFS序列是由BFS搜索过程得来的,而我们知道同一个树的BFS序列,访问同一个节点的子节点时,各个子节点的访问顺序是不确定的。从序列本身入手的话,就要找到每一个节点在树边中的位置处理这很不自然。事实上的可以把整个树用邻接表存起来,然后对每个节点的相邻节点按照在所给序列中的出现位置排序,然后直接对排序处理后的树跑一遍BFS,看所得到的BFS序列和待判断的是否相同即可。这又是一个换一个角度豁然开朗的题。

#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<ctime>
#include<cstring>
#include<string>
#include<float.h>
#include<stack>
#include<unordered_map>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 1<<30;
const int MOD = 998244353;
const int maxn = 200005;

int n;
vector<int> G[maxn];
int a[maxn];
int idx[maxn];
bool vis[maxn];

bool cmp(int u, int v) {
	return idx[u] < idx[v];
}
bool Solve() {
	queue<int> Q;
	memset(vis, 0, sizeof(vis));
	Q.push(1); vis[1] = 1;
	vector<int> tmp;

	while (Q.size()) {
		int now = Q.front(); Q.pop();
		tmp.push_back(now);
		for (int i = 0; i < G[now].size(); ++i) {
			int v = G[now][i];
			if (!vis[v]) { Q.push(v); vis[v] = 1; }
		}
	}
	for (int i = 0; i < n; ++i)if (tmp[i] != a[i + 1])return false;
	return true;
}
int main()
{

	while (~scanf("%d", &n)) {
		for (int i = 1; i <= n; ++i)G[i].clear();
		_for (i, 0, n - 1) {
			int u, v; scanf("%d%d", &u, &v);
			G[u].push_back(v);
			G[v].push_back(u);
		}
		_rep(i, 1, n) { scanf("%d", &a[i]); idx[a[i]] = i; }
		_rep(i, 1, n) sort(G[i].begin(), G[i].end(), cmp);
		bool ans = Solve();
		if (ans)puts("Yes");
		else puts("No");
	}


	return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/82377433
今日推荐