题目链接
http://codeforces.com/contest/1037/problem/D
题意
给定n和n-1条边,即一个树图。
然后给定一个BFS序列。
问该BFS序列是否可以从结点1开始进行BFS得到。
题解
模拟给定的BFS序列看是否合法。
初始将结点1放入队列。
从队列中取出结点u,找出与u邻接的且未被访问过的所有vi结点并放入tmp数组中。
求出tmp数组的大小m。
从给定的BFS序列中依次取出m个数放入buf数组中,并依次放入队列。
将tmp数组和buf数组排序,看两数组是否完全一致。
一旦不一致,那么该BFS序列不合法。
debug:
一开始没有注意到“ starting from vertex
1”,WA了两次。
BFS开始的点不是BFS序列的第一个元素,而是结点1.
AC代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+7;
struct edge
{
int to,next;
}e[maxn<<1];
int head[maxn],cnt,a[maxn];
void init()
{
memset(head,-1,sizeof(head));
cnt=-1;
}
void add_edge(int u,int v)
{
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
bool vis[maxn];
int main()
{
int n;
while(~scanf("%d",&n))
{
init();
for(int i=0;i<n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
add_edge(v,u);
}
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
if(a[1]!=1)
{
printf("No\n");
continue;
}
queue<int> que;
memset(vis,false,sizeof(vis));
bool ok=true;
que.push(1);
vis[1]=true;
int j=2;
while(!que.empty())
{
vector<int> tmp,buf;
int u=que.front();que.pop();
for(int i=head[u];i!=-1;i=e[i].next)
{
int v=e[i].to;
if(vis[v]) continue;
tmp.push_back(v);
vis[v]=true;
}
int m=tmp.size();
while(m--)
{
buf.push_back(a[j]);
que.push(a[j]);
j++;
}
if(tmp.size()!=buf.size()) ok=false;
else
{
sort(tmp.begin(),tmp.end());
sort(buf.begin(),buf.end());
for(int i=0;i<tmp.size();i++)
{
if(tmp[i]!=buf[i])
{
ok=false;
break;
}
}
}
if(!ok) break;
}
printf("%s\n",ok?"Yes":"No");
}
return 0;
}