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