版权声明:希望大家读懂代码,而不是复制粘贴提交 https://blog.csdn.net/pythonbanana/article/details/82349093
题意:
给定一个图和一个序列,判断序列是否是该图BFS其中的一个结果(因为BFS选择邻接点的方式有很多种)。
思路:
好吧,比赛的时候没想出来。既然方式是多样的,那么我们就用序列所给的方式来BFS。这个可以通过顺序来实现,在所给序列先出现的就先放入队列,这样就可以按照所给序列方式遍历。我们按照节点在序列出现的先后顺序给每个节点编号,然后给每个点的邻接点按照编号从小到大排序。然后BFS跑一遍,并记录路径。最后比对所得到的路径和所给序列。
具体看代码注释。
AC code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5 + 100;
int n = 0;
vector<vector<int> > mp(maxn);
int vis[maxn],id[maxn],num[maxn],ans[maxn];
bool cmp(int x,int y){//按照编号从小到大排序
return id[x] < id[y];
}
void bfs(){
queue<int> que;
que.push(1);
vis[1] = 1;
int cnt = 0;
ans[++cnt] = 1;
while(!que.empty()){
int u = que.front();
que.pop();
for(int i = 0;i < mp[u].size();++i){
int v = mp[u][i];
if(vis[v] == 0){
que.push(v);
ans[++cnt] = v;//记录路径
vis[v] = 1;//进入队列的全部标记
}
}
}
}
int main(){
while(scanf("%d",&n) != EOF){
memset(vis,0,sizeof(vis));
for(int i = 0;i < n - 1;++i){
int x = 0,y = 0;
scanf("%d %d",&x,&y);
mp[x].push_back(y);mp[y].push_back(x);//邻接表存储
}
for(int i = 1;i <= n;++i){//记录每个数在要判断的序列的编号
scanf("%d",&num[i]);
id[num[i]] = i;
}
for(int i = 1;i <= n;++i){//按照路径出现的先后顺序排序
sort(mp[i].begin(),mp[i].end(),cmp);
}
bfs();
int flag = 0;
for(int i = 1;i <= n;++i){
if(ans[i] != num[i]){//比较答案数组与序列是否一致
flag = 1;
printf("No\n");
break;
}
}
if(flag == 0){
printf("Yes\n");
}
}
return 0;
}