[CF1037D]Valid BFS?

题目:Valid BFS?

传送门:http://codeforces.com/problemset/problem/1037/D

分析:

方法一:

1)模拟BFS过程,利用首指针$qh$和尾指针$qt$在题目给定的检查数列上移动。

2)枚举到节点$v$,检查$v$的所有子节点$u$能在排在当前队尾$qt$的后面。

2)检查方式:把$v$的子节点$u$提出来,在题目给定检查序列里、队尾指针$qt$后提出相应长度的序列,各自排序,直接比较。

#include<bits/stdc++.h>
using namespace std;
const int maxN=2e5+5;
vector<int>G[maxN],son[maxN],tmp;
int q[maxN];
void Dfs(int v,int fa){
    for(auto it:G[v])
        if(it!=fa)son[v].push_back(it);
    sort(son[v].begin(),son[v].end());
    for(auto u:G[v])
        if(u!=fa)Dfs(u,v);
}
int main(){
    int n;scanf("%d",&n);
    for(int i=1,u,v;i<n;++i){
        scanf("%d%d",&u,&v);
        G[u].push_back(v);
        G[v].push_back(u);
    }
    for(int i=1;i<=n;++i)scanf("%d",q+i);
    Dfs(1,-1);
    bool pd=true;
    if(q[1]==1){
        int qh=1,qt=2;
        for(int v;qh<qt;){
            v=q[qh++];
            tmp.clear();
            for(int i=qt,tt=qt+son[v].size();i<tt;++i)
                tmp.push_back(q[i]);
            sort(tmp.begin(),tmp.end());
            for(int i=0,tt=(int)tmp.size();i<tt;++i)
                if(son[v][i]!=tmp[i]){pd=false;break;}
            qt+=son[v].size();
        }
    }else pd=false;
    puts(pd?"Yes":"No");
    return 0;
}

方法二:

1)如果队首指针$i$是队尾指针j的父节点,那么$q[i]$与$q[j]$必有连边。

2)如果序列合法,则$j$遍历完整个序列。

3)如果序列不合法,则$j$在某些边无法被遍历到,$j$也无法遍历完整个序列。

#include <bits/stdc++.h>
using namespace std;
const int maxN=2e5+5;
map<int,int> mp[maxN];
int q[maxN];
int main(){
    int n;scanf("%d",&n);
    for(int i=1,u,v;i<n;++i){
        scanf("%d%d",&u,&v);
        mp[u][v]=mp[v][u]=1;
    }
    for(int i=1;i<=n;++i)scanf("%d",q+i);
    if(q[1]==1){
        int i=1,j=2;
        for(;i<=n;++i)
            for(;mp[q[i]][q[j]];++j);
        if(j==n+1)puts("Yes");else puts("No");
    }else puts("No");
    return 0;
} 

猜你喜欢

转载自www.cnblogs.com/hjj1871984569/p/10403109.html
今日推荐