星星之火

[codeforces 1037D] Valid BFS? 解题报告(验证bfs序,思维题)

题目链接:http://codeforces.com/problemset/problem/1037/D

题目大意:

给出一棵树,询问一个序列是否可能为这棵树从节点1开始遍历的bfs序

题解:

对于每个节点,令其权值等于该元素在给序列中出现的位置

把每个节点的出边按照到达点的权值排序,来一次bfs得到一个bfs序,判断当前bfs序与给定序列是否相等即可

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<vector> 
#include<queue>
using namespace std;

const int N=2e5+15;
int n,m,s;
int vis[N],giv[N],u[N],v[N],pos[N];
struct node
{
    int y,val;
};
bool operator < (node x,node y) {return x.val<y.val;}
vector<node> g[N];
vector <int> p;
inline int read()
{
    char ch=getchar();
    int s=0,f=1;
    while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0'&&ch<='9') {s=(s<<3)+(s<<1)+ch-'0';ch=getchar();}
    return s*f;
}
void bfs()
{
    queue <int> q;
    vis[1]=1;
    q.push(1);
    while (!q.empty())
    {
        int k=q.front();q.pop();
        p.push_back(k);
        for (int i=0;i<g[k].size();i++)
        {
            int y=g[k][i].y;
            if (vis[y]) continue;
            vis[y]=1;
            q.push(y);
        }
    }
}
int main()
{
    n=read();
    for (int i=1;i<n;i++)
    {
        u[i]=read();v[i]=read();
    }
    for (int i=1;i<=n;i++)
    {
        giv[i]=read();
        pos[giv[i]]=i;
    }
    for (int i=1;i<n;i++)
    {
        g[u[i]].push_back((node){v[i],pos[v[i]]});
        g[v[i]].push_back((node){u[i],pos[u[i]]});
    }
    for (int i=1;i<=n;i++) sort(g[i].begin(),g[i].end());
    /*for (int i=1;i<=n;i++) 
    {
        for (int j=0;j<g[i].size();j++) printf("%d ",g[i][j].val);
        printf("\n");
    }*/
    bfs();
    bool flag=1;
    for (int i=1;i<=n;i++) if (p[i-1]!=giv[i]) {flag=0;break;}
    if (flag) puts("Yes");
    else puts("No");
    return 0;
}

 

posted @ 2018-10-09 10:35  星星之火OIer  阅读(328)  评论(0编辑  收藏  举报