Valid BFS -Manthan, Codefest 18 (rated, Div. 1 + Div. 2)-D题

版权声明:希望大家读懂代码,而不是复制粘贴提交 https://blog.csdn.net/pythonbanana/article/details/82349093

题意:
给定一个图和一个序列,判断序列是否是该图BFS其中的一个结果(因为BFS选择邻接点的方式有很多种)。
思路:
好吧,比赛的时候没想出来。既然方式是多样的,那么我们就用序列所给的方式来BFS。这个可以通过顺序来实现,在所给序列先出现的就先放入队列,这样就可以按照所给序列方式遍历。我们按照节点在序列出现的先后顺序给每个节点编号,然后给每个点的邻接点按照编号从小到大排序。然后BFS跑一遍,并记录路径。最后比对所得到的路径和所给序列。
具体看代码注释。

AC code:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 2e5 + 100;
int n = 0;
vector<vector<int> > mp(maxn);
int vis[maxn],id[maxn],num[maxn],ans[maxn];
bool cmp(int x,int y){//按照编号从小到大排序 
    return id[x] < id[y];
}
void bfs(){
    queue<int> que;
    que.push(1);
    vis[1] = 1;
    int cnt = 0;
    ans[++cnt] = 1;
    while(!que.empty()){
        int u = que.front();
        que.pop();
        for(int i = 0;i < mp[u].size();++i){
            int v = mp[u][i];
            if(vis[v] == 0){
                que.push(v);
                ans[++cnt] = v;//记录路径 
                vis[v] = 1;//进入队列的全部标记 
            }
        }
    }
}
int main(){
    while(scanf("%d",&n) != EOF){
        memset(vis,0,sizeof(vis));
        for(int i = 0;i < n - 1;++i){
            int x = 0,y = 0;
            scanf("%d %d",&x,&y);
            mp[x].push_back(y);mp[y].push_back(x);//邻接表存储 
        }
        for(int i = 1;i <= n;++i){//记录每个数在要判断的序列的编号 
            scanf("%d",&num[i]);
            id[num[i]] = i;
        }
        for(int i = 1;i <= n;++i){//按照路径出现的先后顺序排序 
            sort(mp[i].begin(),mp[i].end(),cmp);
        }
        bfs();
        int flag = 0;
        for(int i = 1;i <= n;++i){
            if(ans[i] != num[i]){//比较答案数组与序列是否一致 
                flag = 1;
                printf("No\n");
                break;
            }
        }
        if(flag == 0){
            printf("Yes\n");
        }
    }   
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/pythonbanana/article/details/82349093