Codeforces 1037D Valid BFS? (BFS、STL)

题目链接

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;
}

猜你喜欢

转载自blog.csdn.net/qq_37685156/article/details/82351917